Re: [racket-users] [ANN] Splitflap: generating valid Atom and RSS feeds

2021-10-27 Thread Jon Zeppieri
https://github.com/97jaz/datetime-lib

On Wed, Oct 27, 2021 at 10:05 AM 'Joel Dueck' via Racket Users
 wrote:
>
> On Tuesday, October 26, 2021 at 1:39:21 PM UTC-5 zepp...@gmail.com wrote:
>>
>> To the extent that validation is a concern, gregor is (despite the
>> `tz/c` issue) much better, on the whole, than racket/base's `date` and
>> `date*` structs, which will happily let you construct things like "the
>> 31st of February."
>
>
> I fully agree with that. ...Didn't you mention on Slack while back that you 
> had a replacement for gregor on a shelf somewhere? ;)
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/77f80d13-2aa3-4b88-b175-6c39f2ce2ef7n%40googlegroups.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzAPrR7cM8fJrzvEdfBi%3DJN%2BEY%3DKUa_61ng70-%2BOF4WTQ%40mail.gmail.com.


Re: [racket-users] [ANN] Splitflap: generating valid Atom and RSS feeds

2021-10-26 Thread Jon Zeppieri
On Tue, Oct 26, 2021 at 2:18 PM 'Joel Dueck' via Racket Users
 wrote:
>
>
>
> On Tuesday, October 26, 2021 at 12:30:59 PM UTC-5 Sage Gerard wrote:
>>
>> Yes, but I'm talking about code we were asked to give feedback on. I focus 
>> on `tz/c` because it is documented as a flat contract that checks for "an 
>> identifier from the IANA tz database", but it does not parse the timezone 
>> name to check correctness.
>>
>> My feedback says no validation occurs for the timezone name in a parameter 
>> for Splitflap. Joel indicated that parameter will go away below, and I'm 
>> glad to know of the tzinfo package. But if a limitation in gregor's 
>> contracts would oblige you to use tzinfo for validation, then I'd want to 
>> know that so that I can assess how much of gregor I really need. It still 
>> seems like the timezone data is the hard part, so use a timezone dependency 
>> instead of a dependency that misleads the user into incomplete validation
>
> It does seem odd that tz/c uses string? instead of tzid-exists? I’m wondering 
> if that could be changed without breaking a lot of stuff. If not, then it 
> *might* be worth keeping my own feed-timezone parameter that allows only 
> (integer-in -64800 64800). On the other hand, it is also true that if an 
> invalid time zone is supplied anywhere along the way to building the feed 
> data, an exception is going to occur before the feed is generated, which is 
> what I care about for the most part.

I agree, and I'm the one who wrote `tz/c` the way it is. Go figure. As
you pointed out, the issue with changing it now is backwards
compatibility. Anyhow, I'm definitely open to suggestions.

>
> In general I appreciate feedback like Sage’s from people who think a lot more 
> carefully than I do about dependencies. I like knowing that if someone has 
> differing time zones for different items within a feed, or cares about 
> gap/overlap resolution, etc, I can let them use gregor to handle it. It's not 
> something I ever encountered in building CMSs or publishing podcasts, but 
> also you never know what a feed will be used for. I will probably experiment 
> with reducing the dependency down to tzinfo/tzdata and using Racket’s native 
> date structs.

[Disclaimer: since I am the author of `gregor`, you should definitely
take into account that I'm biased -- though, maybe not as much as
you'd expect. I'm aware of a bunch of design mistakes I made in
gregor.]

To the extent that validation is a concern, gregor is (despite the
`tz/c` issue) much better, on the whole, than racket/base's `date` and
`date*` structs, which will happily let you construct things like "the
31st of February." And yes, this needs to be balanced against the cost
of taking on an additional dependency.

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxyF3_tdb7%2BxOtnR%2BhtbS1LNznChzUAVOG1W7mctiK%3Dakg%40mail.gmail.com.


Re: [racket-users] [ANN] Splitflap: generating valid Atom and RSS feeds

2021-10-26 Thread Jon Zeppieri
On Tue, Oct 26, 2021 at 12:01 PM Sage Gerard  wrote:
>
> I can understand wanting gregor for timezone offsets when constructing 
> moments, but...
>
> Assuming I have the right repository link, gregor's tz/c contract is only 
> (or/c string? (integer-in -64800 64800)) [1]. I can set the feed-timezone 
> parameter in Splitflap to an arbitrary string and the guard won't stop me.

I'm guessing you haven't actually tried this:

```
> (moment 2000 #:tz "arbitrary string")
. . Library/Racket/8.0/pkgs/tzinfo/tzinfo/private/tzfile-parser.rkt:21:0:
Cannot find zoneinfo file for [arbitrary string]
```

> The IANA's timezone database changed this month, and gregor's last commit was 
> 2 years ago.

Gregor's repo doesn't contain the IANA tzdb and prefers to rely on the
system's zoneinfo files. Every contemporary Unix (including MacOS)
ships with this data and updates it with OS updates. Windows is a
different story (though I know that in recent years, parts of the
Windows ecosystem works with IANA zones, so maybe those files exist
somewhere?).  You're right that the tzdata package has old data. It
would probably make sense for someone who runs Windows to maintain it.
It comes with a script that can update the package for a new version
of the tzdb. I'll do that right now, in fact. Thanks for reminding me.

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzEQBkv1z2T_T4KDhayoPQbeCe%3D%3Dai8YJJKnAZ4z_dUKA%40mail.gmail.com.


Re: [racket-users] Redirecting shared lib stdout

2021-05-12 Thread Jon Zeppieri
Can you use BinaryenModuleWriteText instead? It looks like it was
added to address your use case. -J

On Wed, May 12, 2021 at 3:49 AM Paulo Matos  wrote:
>
> Hi,
>
> I have a shared library for which I am creating some bindings:
> https://github.com/pmatos/racket-binaryen
>
> There's a function BinaryenModulePrint that prints a WebAssembly module
> to stdout.
>
> When I wrap it in racket, if I do something like:
> (define mod ...)
> (with-output-to-string (lambda () (BinaryenModulePrint mod)))
>
> The return value will be "" and it will still print the module to
> stdout. I understand! However, I don't know how to solve it in Racket.
>
> In C, things seem easier because I have access to dup2 and pipe in case
> I need to redirect things, however in Racket all my attempts have
> failed.
>
> I have created the simple example:
> ```hello.c
> #include 
>
> void hello(void) {
>   printf("hello world!\n");
> }
> ```
>
> Compile with `gcc -shared -o hello.so hello.c`.
>
> Then:
> ```hello.rkt
> #lang racket/base
>
> (require racket/port
>  ffi/unsafe
>  ffi/unsafe/define)
>
> (define libhello (ffi-lib "/home/pmatos/dev/tmp/ffi-hello-world/hello.so"))
> (define-ffi-definer define-hello libhello)
> (define-hello hello (_fun -> _void))
> (with-output-to-string hello)
> ```
>
> Here's the issue! In C, I can do something like:
> ```hello-fix.c
> #include 
> #include 
> #include 
> #include 
>
> extern void hello(void);
>
> int main(void) {
>   int filefd = open("test.txt", O_WRONLY|O_CREAT, 0666);
>   dup2(filefd, fileno(stdout));
>   hello();
>
>   return 0;
> }
> ```
> Compile with `gcc -o hello hello.c hello-fix.c`
>
> This will, send the output of hello() to a file. Now, in racket
> preferably I want to connect what is sent to raw stdout, fd 1, to
> current-output-port.
>
> My thought was that I could create a dup2 ffi binding, and use
> unsafe-port->file-descriptor to install the racket pipe file descriptor
> in stdout using the dup2 ffi binding but it doesn't work.
>
> And it doesn't work because the unsafe-port->file-descriptor returns #f,
> even though port-waiting-peer? return #f as well (which sort of hints
> that maybe the documentation of unsafe-port->file-descriptor is
> incomplete.
>
> The start of my attempt would look like this:
>
> ```hello.rkt
> #lang racket/base
>
> (require racket/port
>  ffi/unsafe
>  ffi/unsafe/define
>  ffi/unsafe/port)
>
> (define libhello (ffi-lib "/home/pmatos/dev/tmp/ffi-hello-world/hello.so"))
>
> (define-ffi-definer define-libc (ffi-lib #f))
> (define-ffi-definer define-hello libhello)
>
> (define-libc dup2 (_fun _int _int -> _int))
> (define-hello hello (_fun -> _void))
>
> (define-values (in out) (make-pipe))
>
> ;; FAILS because (unsafe-port-> ...) return #f
> (dup2 (unsafe-port->file-descriptor out) 1)
>
> ;;...
> ;; connect the other end of the port to current-output-port
> ;; and use a thread to copy-port
> ```
>
> Surely there must be a better way than this and I would be surprised if
> there isn't already something out there in a library but I haven't found
> anything yet. Any help here would be great.
>
> Thanks,
>
> --
> Paulo Matos
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/87r1icxuhi.fsf%40linki.tools.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzGAaw3d4-0dc0q%2BPqDyg%2Boh-Nm7bitQ3g%3DyqsUtuqLOw%40mail.gmail.com.


Re: [racket-users] unicode (or just plain byte) regular expression positions?

2021-01-18 Thread Jon Zeppieri
On Mon, Jan 18, 2021 at 10:53 PM Tim Meehan  wrote:
>
> Say that I have a strange character group that I want to find in a binary 
> file.
> I wanted to use something like this:
>
> (define needle (list->string (map integer->char (list #xab #xcd #xef
> (define needle-offset
>   (call-with-input-file "big_binary_blob.bin"
> #:mode 'binary
> (λ (p)
>   (regexp-match-positions (regexp needle) p
>
> The "regexp-match-positions" returns #f (even though I know that needle is in 
> there, I put it there). Is there a better way to go about this? The binary 
> blob is about 100 MiB or so, if that helps.


You're searching for a certain unicode codepoint sequence (U+00AB,
U+00CD, U+00EF) in a string, but I think you're trying to search for a
byte sequence in a byte string. You can read in the file as bytes and
use a byte regexp. So:

(define needle (list->bytes (list #xab #xcd #xef)))
(define needle-offset
  (call-with-input-file "big_binary_blob.bin"
#:mode 'binary
(λ (p)
  (regexp-match-positions (byte-regexp needle) p

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwCcTvg8sNJphkWHe%3DUDpV_c3dLKLReTX6kL%3DD2ZVOOAA%40mail.gmail.com.


Re: [racket-users] Match: non-greedy, and also repeated elements?

2020-12-31 Thread Jon Zeppieri
Right... except that I completely misread your first example, which is
not at all the same as my example with `cons` patterns. Sorry about
that.

On Thu, Dec 31, 2020 at 2:06 PM Jon Zeppieri  wrote:
>
> On Wed, Dec 30, 2020 at 2:24 PM David Storrs  wrote:
> >
> > First off, is there a way to make ... in a pattern match non-greedily?  
> > i.e., match as *few* elements as possible instead of as many?
>
> As far as I know, no. However, if your first example is really
> illustrative of what you're trying to do, you could just use a `cons`
> pattern instead of a `list` pattern:
>
> (match (list '(a b c) '(d e c))
>   [(list (cons _ xs) (cons _ ys))
>#:when (equal? xs ys)
>'ok]
>   [else 'nope])
> => 'nope

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxw3Pywy_Hh%3D7H3CRKT2OfnqAksb3r2jwMrqvrNvDqdt7g%40mail.gmail.com.


Re: [racket-users] Match: non-greedy, and also repeated elements?

2020-12-31 Thread Jon Zeppieri
On Wed, Dec 30, 2020 at 2:24 PM David Storrs  wrote:
>
> First off, is there a way to make ... in a pattern match non-greedily?  i.e., 
> match as *few* elements as possible instead of as many?

As far as I know, no. However, if your first example is really
illustrative of what you're trying to do, you could just use a `cons`
pattern instead of a `list` pattern:

(match (list '(a b c) '(d e c))
  [(list (cons _ xs) (cons _ ys))
   #:when (equal? xs ys)
   'ok]
  [else 'nope])
=> 'nope

And that makes a nice segue into your second question:

> Second, is there a way to make one pattern refer to an earlier pattern in the 
> same match clause?

If we're limiting this to variable patterns, then yes. The
documentation says: "If an id is used multiple times within a pattern,
the corresponding matches must be the same according to
(match-equality-test), except that instances of an id in different or
and not sub-patterns are independent." So, assuming that
`(match-equality-test)` is `equal?` -- which is the default -- the
above could also be written as:

(match (list '(a b c) '(d e c))
  [(list (cons _ xs) (cons _ xs))
   'ok]
  [else 'nope])

Similarly, your second example could be written as:

(match '(a b c c d)
  [(list _ ... x x _ ...)
   'ok]
  [else 'nope])


However, I have seen some issues with this feature (using the same var
pattern multiple times to get an equality restriction). Most recently:
https://github.com/racket/racket/issues/3425

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzm-hq8DRVF5-Ur_Q%3DdxCeQVeARERjKzxQ%2BVUU-18dsrg%40mail.gmail.com.


Re: [racket-users] Trouble with `set-copy`

2020-12-08 Thread Jon Zeppieri
I think that's this bug
[https://github.com/racket/racket/commit/543dab59640fa5e911443baaadaae471406dbf40],
which should be fixed in 7.9. - Jon

On Tue, Dec 8, 2020 at 7:19 PM Nathaniel W Griswold
 wrote:
>
> I don’t know if i’m missing something or what, but the following is confusing 
> me:
>
> (let ([test (mutable-seteqv)])
>   (for* ([i (in-range 1000)]
>  [j (random 0 1000)])
> (set-add! test j))
>   (let ([test-copy (set-copy test)])
> (printf "test-copy=~a\n" (set->list test-copy))
> (printf "Equal from stream is ~a\n" (equal? (list->seteqv (set->list 
> test-copy)) test
>
> prints something like:
> test-copy=(31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 
> 9 8 7 6 5 4 3 2 1 0)
> Equal from stream is #f
> Equal regular is #t
>
>
> Why is this?
>
> Thanks
>
> Nate
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/ED9A219D-41D8-42BF-9C67-9887ADFB268B%40manicmind.earth.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwNX4HXJ2YJeEAem42VmfmG3hi0H-2PrKetsg_Z%2Bwh16g%40mail.gmail.com.


Re: [racket-users] Why is get-impure-port* slower than a system call to curl?

2020-09-14 Thread Jon Zeppieri
I ran a few tests where I fetch the google homepage via curl,
get-impure-port, and get-impure-port*. Curl does, in fact, seem to be
faster, but not nearly so much so to account for the delays in that
video. So, one thing to check is if the racket code gets slower
results when requesting arbitrary urls vs. when requesting that
specific server.

It could be an issue with the requests headers that you're sending
(which is to say, the library defaults) vs. what curl is sending. Or
it could be a bad interaction with Nagle's algorithm, though that
seems unlikely with an http GET, since the most likely culprit would
be separate flushes of header and body data -- and there is no body in
a GET request. I think maybe all of the things you tried use http 1.0
requests by default (simple-http reuses the code from
net/http-client), so you might want to try explicitly using 1.1.




On Mon, Sep 14, 2020 at 3:57 PM Stephen Foster  wrote:
>
> Finally circling back to this issue.  I've disabled debugging in DrRacket and 
> also done a test outside of DrRacket.  It's still slow. :(
>
> I also tried the newer HTTP client: 
> https://docs.racket-lang.org/http-easy/index.html.  Like the others, it is 
> also slow.
>
> I'll do some more digging.  I'm currently trying to figure out if this is a 
> "just me" / "just my system" problem.  So... I'd be grateful if anyone who 
> has written code that sends HTTP requests from Racket could chime in with: 1) 
> I can confirm that sending HTTP requests from Racket has always been fast for 
> me, or 2) I too have noticed Racket HTTP requests are slow.
>
> (Note that by "slow", I mean: takes noticeably longer than curl.)
>
>
>
> On Tue, Jul 7, 2020 at 12:21 PM Jon Zeppieri  wrote:
>>
>> Hi Stephen,
>>
>> Your video shows you running this code in DrRacket with debugging
>> enabled. That usually affects performance. Have you made measurements
>> when running this code outside of DrRacket?
>>
>> - Jon
>>
>>
>> On Tue, Jul 7, 2020 at 2:13 PM Stephen Foster  
>> wrote:
>> >
>> > I'm considering using Racket to remake my 3D game CodeSpells.  I'm using 
>> > http requests to have Unreal Engine and Racket talk to each other.
>> >
>> > When I use the http/request library, Racket fires off its GET request much 
>> > slower than if it were to do a system call to curl.  (Same is true if I 
>> > use simple-http, which makes me think the problem might be a deep one.)
>> >
>> > Here's a video to demo the issue.  Notice how, with curl, the experience 
>> > is playable, whereas with the Racket function, there's way too much time 
>> > between the spell landing and the effect occurring:
>> >
>> > https://youtu.be/jTqUFVlfBFA
>> >
>> > Obviously, I'd like to do things in a Rackety way.  But I'm not above 
>> > doing things the silly way.  I'd just be grumpy about it.
>> >
>> > Any ideas?
>> >
>> >
>> >
>> > --
>> > 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+unsubscr...@googlegroups.com.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/racket-users/997693d6-b94a-4f69-85cf-aa475c807b20n%40googlegroups.com.
>
>
>
> --
>
>
> Stephen Foster
> ThoughtSTEM Co-Founder
> 318-792-2035

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxyzT9z9inrjoLumvK%3DZi4CNpBo0RpMuOkkwUs4WG2g4Gg%40mail.gmail.com.


Re: [racket-users] Why is get-impure-port* slower than a system call to curl?

2020-07-07 Thread Jon Zeppieri
Hi Stephen,

Your video shows you running this code in DrRacket with debugging
enabled. That usually affects performance. Have you made measurements
when running this code outside of DrRacket?

- Jon


On Tue, Jul 7, 2020 at 2:13 PM Stephen Foster  wrote:
>
> I'm considering using Racket to remake my 3D game CodeSpells.  I'm using http 
> requests to have Unreal Engine and Racket talk to each other.
>
> When I use the http/request library, Racket fires off its GET request much 
> slower than if it were to do a system call to curl.  (Same is true if I use 
> simple-http, which makes me think the problem might be a deep one.)
>
> Here's a video to demo the issue.  Notice how, with curl, the experience is 
> playable, whereas with the Racket function, there's way too much time between 
> the spell landing and the effect occurring:
>
> https://youtu.be/jTqUFVlfBFA
>
> Obviously, I'd like to do things in a Rackety way.  But I'm not above doing 
> things the silly way.  I'd just be grumpy about it.
>
> Any ideas?
>
>
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/997693d6-b94a-4f69-85cf-aa475c807b20n%40googlegroups.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxx2%2BrwSw1FiDXvtw9ErNXor-QffeUF21%2BNpsiM%2BZviRNQ%40mail.gmail.com.


Re: [racket-users] Re: [racket] Web Framework Benchmarks

2020-06-09 Thread Jon Zeppieri
On Tue, Jun 9, 2020 at 7:59 AM Bogdan Popa  wrote:
>
> I think we'd need to also set `SO_REUSEPORT', which is not available on
> all platforms, to support multiple processes listening on the same port
> without reusing file descriptors.

And even where it is available, it doesn't work the same way. The
Linux version can be used to load balance accept()s across processes,
but the BSD version (also in OS X) cannot. (FreeBSD apparently has a
variant, SO_REUSEPORT_LB, that behaves like the Linux version of
SO_REUSEPORT.)

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxxg_CanKg1Kgj0XP4%2B8aaGNB64ysmmGPCuK4PXq0nmQhg%40mail.gmail.com.


Re: [racket-users] br-parser-tools question

2020-06-08 Thread Jon Zeppieri
On Mon, Jun 8, 2020 at 8:36 PM jon stenerson  wrote:
>
> Hi all,
>
> I don't understand the error message here. The parser seems to be
> looking for a position-token but the lexer is sending srcloc-tokens? Is
> there a simple fix? Using Racket 7.7 on WIn 10.

Hi Jon,

Yes, you're right, and there is a simple fix. Instead of using
`lexer-srcloc`, you can use `lexer-src-pos`. The former seems to be an
addition to the `br-` variant of parser-tools, but I don't see any
indication that the lexers it generates can be used with the yacc
tools. (I could be wrong about that.)

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxyi_ubBaRhs%3DHD9R7UxTYmePqqVLbsbOFcHzg8%2BQfR1KQ%40mail.gmail.com.


Re: [racket-users] Some stuff about "case".

2020-06-01 Thread Jon Zeppieri
On Mon, Jun 1, 2020 at 3:52 PM Jens Axel Søgaard  wrote:
>
> Den man. 1. jun. 2020 kl. 20.53 skrev Christopher Lemmer Webber 
> :
>
>
> I think `case` were more important before `match` arrived.
> If you want to see how `case` can be implemented without hash-tables, look at
> William D Clinger's paper:
>
> http://scheme2006.cs.uchicago.edu/07-clinger.pdf
>
> /Jens Axel

The Racket implementation of case is based on Clinger's paper. And
Clinger's approach does, in fact, use hash tables, except that in the
Larceny implementation, the hash table fetch is open-coded by case
(IIRC), which is not the case in Racket (unless it gets inlined by the
compiler in the CS version, I suppose, though I don't know if that's
actually possible).

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxx1rBXHD%2B9sLH4x6kBJoE2SbKHKp%3D_PGWCZVmqjAO7Qiw%40mail.gmail.com.


Re: [racket-users] Trouble shooting net/http-client

2020-05-15 Thread Jon Zeppieri
I can't reproduce this with a simple example.

```
#lang racket/base

(require net/http-client)

(define data "hello world!")

(http-sendrecv "postman-echo.com"
   "/post"
   #:ssl? #f
   #:method #"POST"
   #:data data)
```

Maybe you could post your code?

- Jon


On Fri, May 15, 2020 at 3:57 PM je back  wrote:
>
> I'm having trouble with formatting the #:data parameter to a http-sendrecv 
> request.  If I insert the string literal after #:data "my string" it works, 
> if I bind the string to a symbol (define my-string "my string") and call with 
> #:data my-string i get an error from the severs: HTTP/1.1 400 Bad Request .  
> Is there a way to echo or examine the request as sent?
>
> Also, I can't figure out where the source code for this library is located.
>
> Thanks,
> Jan Erik
>
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/b786e6fa-512b-4694-885a-afde1a011cf1%40googlegroups.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxxQ-LA9ood8n5xca3jQf-ux%3DcWfPFwb2G-ijVeVreKhvQ%40mail.gmail.com.


Re: [racket-users] trickiness about the order of definitions in GUI code

2020-05-06 Thread Jon Zeppieri
On Wed, May 6, 2020 at 7:50 PM James Platt  wrote:
>
> I'm working on organizing and documenting some things and I have some code, 
> below, which works but I don't understand why.  Specifically, why don't I get 
> an error about table3 not being defined?

The reason you don't get an error for the code you posted is because
the mention of `table3` (before its definition) in `info-menu-item` is
inside a function body. The referent of the name `table3` isn't
required to define `info-menu-item`; it's sufficient to know that it
refers to _something_, and that it will be available when that
function is (later) called.

> In other words, I want to be able to define table3 in one file which requires 
> the file where row-edit-menu is defined but I can't seem to figure out how to 
> get this to work.

It's a bit trickier to define these things in separate files, because
their definitions refer to each other (though indirectly in this
case), and the module system does not tolerate cyclic dependencies.
The most straightforward way to break the cycle would be to take
advantage of the fact that `table3` and `info-menu-item` each depends
on `row-edit-menu`, and `info-menu-item` further depends on `table3`,
but `row-edit-menu` doesn't depend on either. So the dependencies
aren't really cyclical. You can divide stuff up into separate modules
like so:

menu.rkt
```
#lang racket

(require racket/gui/base)

(provide frame3
 row-edit-menu)

(define frame3
  (new frame%
   [label "myTable 3"]
   [width 800]
   [height 600]))

(define row-edit-menu (new popup-menu%))
```


table.rkt
```
#lang racket

(require racket/gui/base
 qresults-list
 "menu.rkt")

(provide table3
 add-rows)

;set up columns
(define (column1 data) (vector-ref data 0))
(define (column2 data) (vector-ref data 1))

(define my-columns
  (list
   (qcolumn "Column1" column1 column1)
   (qcolumn "Column2"
(λ (row)
  ;(displayln row)
  ;(displayln (db-row-ref row "Column2" headers 1))
  (if (number? (column2 row)) (number->string (column2
row)) "");This allows a cell to be blank.
  ;(number->string (column2 row))
  )
column2)))

(define table3
  (new (class qresults-list% (init) (super-new))
   [parent frame3]
   [pref-tag 'preferences-tag]
   [selection-type 'multiple]
   [right-click-menu row-edit-menu]))

(define (add-rows)
  (send table3 add-row (vector "R1C1" 10))
  (send table3 add-row (vector "R2C1" 11))
  (send table3 add-row (vector "R3C1" 12))
  (send table3 add-row (vector "R4C1" 13)))
```


menu-item.rkt
```
#lang racket

(require racket/gui/base
 "menu.rkt"
 "table.rkt")

(provide info-menu-item)

(define info-menu-item
  (new menu-item%
   [label "info"]
   [parent row-edit-menu]
   [callback (λ (menu-item event)
   (message-box "Info"
(~a "You have selected " (length (send
table3 get-selected-row-indexes)) " rows")
#f))]))
```


main.rkt
```
#lang racket

(require "menu.rkt"
 "table.rkt")

(send frame3 show #t)
(add-rows)
```

Hope that helps.

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwofLFVTkcGii%2BtLGKYCBFVNY2Tw9m8ZNjR--Hh_FRtEw%40mail.gmail.com.


Re: [racket-users] a question or two regarding Gregor

2020-04-30 Thread Jon Zeppieri
Only a small number of zone formats are supported in parsing mode.
This is discussed a bit in https://github.com/97jaz/gregor/issues/25.
The situation could definitely be improved.

- Jon

On Thu, Apr 30, 2020 at 11:33 AM Tim Hanson  wrote:
>
> p.s. I'm stuck on parsing one pattern that comes up in my data. Here's a 
> corresponding test:
>
>   (parameterize ([current-locale "en"])
> (check-equal?
>  (parse-datetime "Sun, 21 Jun 2015 17:50:44 -0500 (CDT)" "EEE, dd MMM 
>  HH:mm:ss  ()") (datetime 2015 6 21 17 50 44)))
>
> that fails with
> ../../../../../Library/Racket/7.6/pkgs/gregor-lib/gregor/private/pattern/ast/zone.rkt:40:2:
>  match: no matching clause for (Zone ... 'offset-name 'long)
>
>
> I'm looking at the source code but am not quite sure. Are zone descriptors 
> such as CDT supported? (I also tried (zzz), but it also fails with
> no matching clause for (Zone ... 'offset-name 'short).)
>
>
> In
>   https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
>
> I find an example:
>
> Pattern Result (in a particular locale)
> .MM.dd G 'at' HH:mm:ss zzz  1996.07.10 AD at 15:08:56 PDT
>
> which makes me think it should perhaps work.
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/10f6f25d-6da8-4bbb-9459-ce63ae071c34%40googlegroups.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxw3xz65z7Lm60qsYGhkBzR7Du36i9HfCQHzk7sdXxiytg%40mail.gmail.com.


Re: [racket-users] Question on test failures sorting a BTS

2020-04-27 Thread Jon Zeppieri
In addition to what Jens said, you should probably give a definition
of a BST at the top, and give some thought to the question of why a
BST is not simply the same thing as a node.

- Jon

On Sun, Apr 26, 2020 at 10:36 PM Kristina Marie  wrote:
>
> Hello,
> I am trying to use HtDF to create a function to sort a Binary Search Tree. I 
> am in an intro class so this may be a simple question. I did the following:
>
> ;define-struct a node
> (define-struct node (left value right))
> ;BTS leafs
> (define a-node(make-node null "A" null))
> (define b-node (make-node null "B" null))
> (define e-node (make-node null "E" null))
> (define h-node (make-node null "H" null))
> (define i-node (make-node null "I" null))
>
> ;BTS internal
> (define c-node (make-node a-node "C" b-node))
> (define j-node (make-node h-node "J" i-node))
> (define k-node (make-node j-node "K" null))
> (define f-node (make-node e-node "F" null))
> (define g-node (make-node f-node "G" k-node))
>
> ;Root
> (define root (make-node c-node "D" g-node))
>
> ; Purpose: sort a binary tree
> ; Signature: node -> list
> ; Examples:
> (check-expect (bst-sort null)(list))
> (check-expect (bst-sort a-node)(list "A"))
> (check-expect (bst-sort j-node)(list "H" "I" "J"))
> (check-expect (bst-sort root)(list "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" 
> "K"))
>
> ;Code
> (define (bst-sort nod)
>   (cond
> [(null? nod)(list)]
> [(and (null? (node-left nod)) (null?(node-right nod))) (list(node-value 
> nod))]
>[else
>(string-append (bst-sort (node-left nod) (list (node-value nod)) 
> (bst-sort (node-right nod
>]
>)
>  )
>
> I keep getting this test failure:
> bst-sort: expects only 1 argument, but found 3
>
> It has to due with the two last check-expects failing because of the 
> highlighted line.
>
> I ran this same code with integers and removed the string from append and it 
> passed. Any advice?
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/e5e05ebe-87ed-4d49-8a18-d3b58bae4e38%40googlegroups.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwOOMxMcmTZm7bYJm6D7vM4w1VjORBxcjypWdUCr%3DRduA%40mail.gmail.com.


Re: [racket-users] a question or two regarding Gregor

2020-04-27 Thread Jon Zeppieri
On Mon, Apr 27, 2020 at 2:38 AM Tim Hanson  wrote:
>
> hi, I've installed and am trying out
>
>   Gregor: a date and time library for Racket
>
> and find it to be very powerful and useful.

Thanks!

>
> In my current application (digging through mail headers) I'm wondering 
> whether there is a way to test whether a given date-time format matches 
> without using exceptions. (I assume that would generally be more efficient 
> than catching exceptions.)
> [...]
>
> I thought I'd check here:
> - does this seem like a reasonable idea?

It does to me.

> - is mine an unusual use case and most folks know what format to expect and 
> the exception approach is fine?

Good question. If you're expecting dates/times to come in a variety of
formats, I can see why you'd want to try out a few of them. And that
is made more difficult by having these functions raise exceptions. So
I think it would have been wiser to make these functions behave the
way you've indicated.

Or maybe partially so...?

The exceptions that occur during a parse can come from three (I hope I
counted them all) three distinct sources:
   - Your pattern may be lexically invalid (e.g., `(parse-datetime
"2/29/2000" "M/f/y")`.)
   - Your pattern may fail to match the input (e.g., `(parse-datetime
"2/29/2000" "MMM/d/y")`.).
   - Your pattern may match the input, but the interpretation of the
input as a date, datetime, etc. may refer to a date that does not
exist in the Gregorian calendar (e.g., `(parse-datetime "2/29/1999"
"M/d/y")` or a date-time that does not exist in a local time zone
(e.g., a time between 2-3 am during a transition to Daylight Saving
Time from Standard Time in the U.S.).

I think the first of these would definitely remain an exception. The
second is the most obvious candidate for returning #f instead of
raising. The third is (to me) the least obvious.

> - is there perhaps an elegant way for me to test with a regular expression 
> first rather than adding this function to Gregor?

That would depend on the particular formats you're expecting.

>
> Cheers,
>
> Tim

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzFVQ43L3%3D_61VGTEuoVn-7rZvG5YmHtRO-sw2wM4Xp8A%40mail.gmail.com.


Re: [racket-users] [racket users] struct #:methods question

2020-04-20 Thread Jon Zeppieri
There's no trick to it:

#lang racket/base

(require racket/generic)

(define-generics foo
  (foo-do foo x))

(struct thing (x)
  #:methods gen:foo
  [(define (foo-do f x)
 (thing x))])


On Mon, Apr 20, 2020 at 6:32 PM Kevin Forchione  wrote:
>
> Hi guys,
> How do you return an instance of the structure type from the struct’s 
> #:methods? This is would seem to be a common situation, but it has me stumped.
>
> Kevin
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/EE404363-995C-4888-8B43-E463EB3C7418%40gmail.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxx6b2yq6Sn6zzr49oZqGXc5h4CA-Vj%3DVYEkLbmaBOi3Pg%40mail.gmail.com.


Re: [racket-users] New to racket, help with coursework question

2020-04-19 Thread Jon Zeppieri
Well, this all looks very familiar. Can I ask where this course is offered?


Okay, let's start with part of the problem definition:

> Create a function that calculates the number of days in a month given a year 
> and a month
>
> Call the function number-of-days-in-month, and it's signature is number, 
> number -> number

Let's put these two statements together. In fact, let's start with the
second one, specifically: "[the function's] signature is number,
number -> number." That means the function takes two arguments, both
of which are numbers, and it returns a number. That's not very
informative. If that were all the information you had, you might start
your function definition like this:

(define (number-of-days-in-month one-number a-second-number)
  [ somehow calculate yet a third number ])

But the previous sentence gives you more information. It says, "[the
function] calculates the number of days in a month given a year and a
month." This is a actually a more specific version of what the
signature tells you. Let me reverse the order of the statement to make
this more clear: "Given a year and a month, the function calculates
the number of days in the month."

So the "numbers" in the signature aren't any old numbers. Let's look
at the signature again:
   number, number -> number

The things to the left of the arrow are what the function is given.
The problem says that the function is given a year and a month. So
let's restate the signature, adding that information:
  year-number, month-number -> number

The thing to the right of the arrow is what the function calculates,
in this case the number of days in the given month. (This is where
things get a little complicated. You're trying to calculate the number
of days in the month that you're given. Fine, so why are you given a
year in addition to the month? The answer to this question will help
you when you start to fill in your function body. By the way, I'm not
trying to be patronizing. I'm pretty sure you know the answer to this
question, given what you wrote in your message. But it may help to
think about it this way.) So let's add this information to the
signature:

   year-number, month-number -> number-of-days-in-month

Or, in English: "`number-of-days-in-month` is a function that takes a
year number and a month number and returns the number of days in the
month." If you're skeptical of my claim that this is more specific
than the signature we started with, consider that not all numbers are
valid year-numbers or month-numbers. For example, 2.5 isn't the number
of a year (well, not in the Gregorian calendar, anyhow), and -20 isn't
the number of a month.

So now at least, we should be able to replace the "??"s in your
function skeleton:

(define (number-days-in-month year-number month-number)
  (cond
[

As for the conditional in the function body, go back to the question I
posed above: why are you given a year-number in addition to a
month-number if you're just supposed to find the number of days in a
month?

- Jon



On Sun, Apr 19, 2020 at 2:50 PM Suz Renae  wrote:
>
> I am new to racket (first year student) and since class has been pushed to 
> online only, I am having a harder time.
>
> We are currently working on vectors and hash tables. I feel like I keep 
> overthinking it and keep getting stuck. I know that the first parameter in 
> the function will be the year and the second will be the (vector-ref months 
> x)that I pull from the defined vector.
>
> The question I am having a hard time with and what I have actually done below.
>
> Create a function that calculates the number of days in a month given a year 
> and a month
>
> Call the function number-of-days-in-month, and it's signature is number, 
> number -> number
> Example:
> (number-days-in-month 2016 1) -> 31
> (number-days-in-month 2016 11) -> 30
> (number-days-in-month 2016 12) -> 31
> (number-days-in-month 1900 2) -> 28
> (number-days-in-month 2000 2) -> 29
> (number-days-in-month 2016 2) -> 29
> (number-days-in-month 2200 2) -> 28
>
> What I have so far...
>
> ;Leap Year
> (define (leap-year? year)
>   (and (zero? (modulo year 4))
>(or (not (zero? (modulo year 100)))
>   (zero? (modulo year 400))
>   )
>)
>   )
>
> ;Months with days vector, beginning at an index of 0 since there is not 0th 
> month
> (define months (vector 0 31 28 31 30 31 30 31 31 30 31 30 31))
>
> (check-expect(number-days-in-month 2016 1)31)
> (check-expect(number-days-in-month 2016 11)30)
> (check-expect(number-days-in-month 2016 12)31)
> (check-expect(number-days-in-month 1900 2)28)
> (check-expect(number-days-in-month 2000 2)29)
> (check-expect(number-days-in-month 2016 2)29)
> (check-expect(number-days-in-month 2200 2)28)
>
> I  need help with building the actual function and what conditionals I should 
> be using.
>
> (define (number-days-in month ?? ??)
> (cond
>  [
>
> --
> You received this message because you are subscribed to the Google Groups 
> 

Re: [racket-users] typing variable length argument lists

2020-04-10 Thread Jon Zeppieri
(define (unique [list : (Listof Any)] [message : String] .
[messageargs : Any *])
  ; return the only element of the list, or '() if there is none.
  ; Produce message if not just one.
  (if (equal? 1 (length list)) (car list)
 (begin
   (apply fprintf anomaly message messageargs)
   (if (null? list) list (car list)

On Fri, Apr 10, 2020 at 7:49 PM Hendrik Boom  wrote:
>
> Trying to convert the following to typed Racket:
>
> (define (unique list message . messageargs)
>   ; return the only element of the list, or '() if there is none.
>   ; Produce message if not just one.
>   (if (equal? 1 (length list)) (car list)
>  (begin
>(apply fprintf (cons anomaly (cons message messageargs)))
>(if (null? list) list (car list))
>)
>  )
> )
>
> It's an error message function tat accepts a list to test.
> If the test fails it uses fprintf to print a message with the
> arguments for the ~s items.
>
> I got so far, but I don't know what to do with the . messageargs :
>
> (define (unique [list (Listof Any)] [message : String] . messageargs)
>   ; return the only element of the list, or '() if there is none.
>   ; Produce message if not just one.
>   (if (equal? 1 (length list)) (car list)
>  (begin
>(apply fprintf (cons anomaly (cons message messageargs)))
>(if (null? list) list (car list))
>)
>  )
> )
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/20200410234906.5wy5kgzl2qfwd2db%40topoi.pooq.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwCh5OZSCTujaPCqgKa0uhO_gc7JpaD1jV3jeqC0Wsaxg%40mail.gmail.com.


Re: [racket-users] Best way to say "terminate unless received by X time"

2020-03-24 Thread Jon Zeppieri
On Tue, Mar 24, 2020 at 4:03 PM David Storrs  wrote:
>
> I've got this code:
>
> (thread
>   (thunk
> (let loop ()
>   (define-values (len shost sport) (udp-receive! socket buffer))
>   ...do stuff with the received message...
>  (loop
>
> I'd like to be able to say "If you haven't received a message in X time, kill 
> the thread".  I'm not sure how to enact that; sync/timeout won't do it since 
> the thread won't return.  I've thought of weird signaling systems using 
> channels or set! on some external value or etc, but they are all terrible.
>
> What's the right way to do this?
>

Not quite sure what you mean when you say "sync/timeout won't do it
since the thread won't return." You'll know when you timed-out, so you
can return in that case. Wouldn't something like this work?

```
(thread
 (λ ()
   (let loop ()
 (match (sync/timeout timeout (udp-receive!-evt socket buffer))
   [(list len shost sport)
;; do stuff
(loop)]
   [#f
;; timed out; exit the loop and the thread
(void)]
```

Apologies if I've misunderstood you.

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzgwLVDH-YzNWnMkghy_bMXcMHsujhWAxqHH8U07drDYg%40mail.gmail.com.


Re: [racket-users] [racket users] Generics question

2020-03-03 Thread Jon Zeppieri
On Tue, Mar 3, 2020 at 12:37 PM Kevin Forchione  wrote:
>
> Thanks!  That brings me a little closer in appreciating the comments I’ve 
> read about replacing object-oriented code with structs and methods.
>
> Is this part of the racket/generic or the Multimethods library? The example 
> you provide works from racket/generic, but the search in docs pulls up only 
> the multimethod docs and the examples don’t work from racket/generic.
>
> Kevin

It's in racket/generic. Here's a link to the documentation for
`define/generic`:
https://docs.racket-lang.org/reference/struct-generics.html?q=define%2Fgeneric#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define%2Fgeneric%29%29

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxxfSLiqwYof4DaanadssHMTtR2QTJk2Q1nNRzGssoM1zw%40mail.gmail.com.


Re: [racket-users] [racket users] Generics question

2020-03-03 Thread Jon Zeppieri
Kevin,

This is what `define/generic` is for. In your example:

On Tue, Mar 3, 2020 at 11:08 AM Kevin Forchione  wrote:
>
> (struct A (this other) #:transparent
>   #:methods gen:foo
>   [(define (do-foo foo)
>  (printf "other=~a ~a"
>  (A-this foo)
>  (do-foo (A-other foo])

The call to `(doo-foo (A-other foo))` is simply a recursive call to
the function that you're in the middle of defining. In order to call
the generic method and have it dispatched appropriately, you need to
use `define/generic`:

(struct A (this other) #:transparent
  #:methods gen:foo
  [(define/generic generic-foo do-foo)
   (define (do-foo foo)
 (printf "other=~a ~a"
 (A-this foo)
 (generic-foo (A-other foo])

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzv7S4gnxjZEDT7yD%3Dm8Y4R6t4fCFjFKyixR99r%2Bc15qQ%40mail.gmail.com.


Re: [racket-users] Implications of stateless servlets & how/whether to avoid them

2020-02-20 Thread Jon Zeppieri
Okay, in that case, you really shouldn't add a content-length header. -Jon

On Thu, Feb 20, 2020 at 1:13 PM Bogdan Popa  wrote:
>
>
> Jon Zeppieri writes:
>
> > When you stream the response, it doesn't use a chunked transfer encoding? 
> > -Jon
>
> The web server chunks all responses on HTTP/1.1 connections[1].
>
> I can confirm that the web server works great[2] for streaming uses cases
> like long polling!
>
> [1]: 
> https://github.com/racket/web-server/blob/564120c0f5e4bb959d4592a37037146d8411948e/web-server-lib/web-server/http/response.rkt#L56
> [2]: 
> https://github.com/Bogdanp/nemea/blob/5c8a58121ed9f264277d7eb56187fbeaad506138/nemea/http/reporting.rkt#L18-L35

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxxy_evsbmAPk02K3JX1Z3-sBA5dZDzZ6p8uCtnqicqBvw%40mail.gmail.com.


Re: [racket-users] Implications of stateless servlets & how/whether to avoid them

2020-02-20 Thread Jon Zeppieri
When you stream the response, it doesn't use a chunked transfer encoding? -Jon

On Thu, Feb 20, 2020 at 12:40 PM Jay McCarthy  wrote:
>
> I assume it is not necessary to be totally accurate, but it is good to when 
> you can, because of the Web principle of accepting broad input and producing 
> specific output. I don't know of any existing program (like a proxy or 
> something) that would fail without an accurate length, but it wouldn't 
> surprise me if there was one.
>
> Jay
>
> --
> Jay McCarthy
> Associate Professor @ CS @ UMass Lowell
> http://jeapostrophe.github.io
> Vincit qui se vincit.
>
>
> On Thu, Feb 20, 2020 at 11:17 AM Brian Adkins  wrote:
>>
>> On Monday, December 3, 2018 at 10:49:40 AM UTC-5, Jay McCarthy wrote:
>>>
>>> > I don't know if the Racket web server (or related libraries) currently 
>>> > provide a way to stream data in the response, but that is something I'll 
>>> > definitely need relatively soon (primarily for streaming large CSV/JSON 
>>> > files). If it doesn't exist, I don't mind writing it, but I also don't 
>>> > want to begin with an approach now that might make adding that capability 
>>> > more difficult later. From my brief research, given the output field of 
>>> > the response struct is a lambda, I think I can stream using that (i.e. 
>>> > return a lambda in the response immediately that begins writing the data 
>>> > as it retrieves it) - hopefully the infrastructure doesn't buffer the 
>>> > entire output. Other than something like that, I'm happy to work mostly 
>>> > at the level of functions from requests to responses.
>>>
>>> The reason why responses have the lambda rather than a byte string is
>>> specifically for streaming like you want. Make sure you specify the
>>> correct response size in the headers.
>>
>>
>> Jay, are you sure it's necessary to specify the correct response size in the 
>> headers? This would be extremely inconvenient in a streaming response 
>> scenario. I looked at some similar code in a Rails project, and it appears 
>> I'm only setting Last-Modified, Content-Disposition and Content-Type headers.
>>
>> Yes, I know this is an old thread, but I'm just now having to stream some 
>> CSV files from the web app :)
>>
>> --
>> 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+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/racket-users/995deb39-16f7-432e-8931-3bbae4d86bb7%40googlegroups.com.
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/CAJYbDa%3Dr%2BqARXUCh90Fw1b5c7XqGCyenZcO--t02vK6Sae7wLA%40mail.gmail.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxx8nFCoMsWH-FbQfwGw8KgAyHqeEYdHJbN8GWmyKV3keg%40mail.gmail.com.


[racket-users] join-based tree operations and racket-cs futures

2019-12-11 Thread Jon Zeppieri
I've been playing around with a simple AVL tree that uses the
split/join operations that Adams originally applied to weight-balanced
binary trees[1] and then Blelloch, Ferizovic, and Sun later applied to
other kinds of balanced binary trees.[2] The latter paper concentrates
on how certain operations (union, intersection, difference) are easily
parallelized with an implementation that uses this approach. In their
tests, they saw performance increase linearly up to around 32 cores.

I tried the same thing with futures on racket-cs (since I understand
that it has fewer blocking/synchronized operations than racket-c). On
my 8 core machine, performance is slightly better for a parallel
version of `union` (which is implemented exactly as Blelloch et al.
have it on the second page of their paper) but it's nowhere near a
linear speed-up. The parallel version completes a test in about 80% of
the time that the sequential version does.

The future-visualizer doesn't show any synchronizing or blocking
events (aside from the touches), though I also don't entirely
understand what it does show. What, for example, is indicated by a
thread that has only a very short green horizontal line? Is it just
idle for most of the time?

I'm using futures pretty much the same way that Dominik Pantůček is
using them in his `futures-sort` package, with a parallelism depth
computed from the number of cores available.[3] (Thank you for the
excellent example, by the way, Dominik.)

[1] http://groups.csail.mit.edu/mac/users/adams/BB/
[2] https://www.cs.cmu.edu/~guyb/papers/BFS16.pdf
[3] https://github.com/dzoep/futures-sort/blob/master/main.rkt#L338

My own code has:

(define (parallel-union t1 t2 cmp)
  (let loop ([t1 t1] [t2 t2] [depth (inexact->exact (ceiling (log
(processor-count) 2)))])
(match* (t1 t2)
  [(#f _) t2]
  [(_ #f) t1]
  [(_ (node _ l2 (and (cons k2 _) kv2) r2))
   (define-values (l1 _ r1) (split t1 k2 cmp))
   (cond
 [(fx<= depth 0)
  (define tl (loop l1 l2 (fx- depth 1)))
  (define tr (loop r1 r2 (fx- depth 1)))
  (join tl kv2 tr)]
 [else
  (define tl (future (λ () (loop l1 l2 (fx- depth 1)
  (define tr (loop r1 r2 (fx- depth 1)))
  (join (touch tl) kv2 tr)])])))

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxyUaPFf6Kdum-FuKYunGrPCLsQxMZd3%3D4NR5k5MLqj6yg%40mail.gmail.com.


Re: [racket-users] How to use dates (especially gregor) with Typed Racket?

2019-12-04 Thread Jon Zeppieri
On Tue, Dec 3, 2019 at 8:55 PM Ben Greenman  wrote:
>
> The error is because gregor/time doesn't export a struct. But
> nevermind that, because you're probably best off with an opaque type:
>
> ```
> #lang typed/racket
>
> (require/typed gregor/time
>   [#:opaque Time time?]
>   [time (->* [Integer] [Integer Integer Integer] Time)]
>   [time->iso8601 (-> Time String)])
>
> (require/typed gregor
>   [current-time (->* [] [#:tz String] Time)])
>
> (time->iso8601 (current-time))
> ;; "21:04:25.687808105"
> ```

Also, most operations on the date/time data structures are generic,
which makes it a bit more complicated to use with typed racket. The
generic predicates, like `time-provider?`, should probably map to
union types, like so (though people like Ben, who are more savvy about
typed racket, might have other ideas):

```
#lang typed/racket

(require/typed gregor/time
   [#:opaque Time time?]
   [time (->* [Integer] [Integer Integer Integer] Time)]
   [time->iso8601 (-> Time String)])

(require/typed gregor
   [#:opaque Datetime datetime?]
   [datetime (->* [Integer] [Integer Integer Integer
Integer Integer Integer] Datetime)])

(define-type Time-Provider (U Time Datetime))

(require/typed gregor
   [current-time (->* [] [#:tz String] Time)]
   [->hours (-> Time-Provider Integer)])

(time->iso8601 (current-time))
(->hours (current-time))
```

Also, if you want to be more specific with your types:
```
#lang typed/racket #:with-refinements

(define-type Hour (Refine [n : Integer] (and (>= n 0) (< n 24
(define-type Minute (Refine [n : Integer] (and (>= n 0) (< n 60
(define-type Second (Refine [n : Integer] (and (>= n 0) (< n 60
(define-type Nanosecond (Refine [n : Integer] (and (>= n 0) (< n 10

(require/typed
 gregor/time
 [#:opaque Time time?]
 [time (->* [Hour] [Minute Second Nanosecond] Time)])
```
... though this might make the proof obligations too onerous,
depending on how you're using the library.

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzq0S6-fzMA%3D%2BVfdxH7ZBqkDFO%2BUHt_Nabj%3DOipP%3DMMwQ%40mail.gmail.com.


Re: [racket-users] Re: raco distribute and runtime paths, conditioned on whether a package was installed at compile time

2019-11-12 Thread Jon Zeppieri
On Tue, Nov 12, 2019 at 10:13 PM Matthew Flatt  wrote:
>
> At Tue, 12 Nov 2019 19:46:01 -0700, Matthew Flatt wrote:
> > Although you can find the files using `find-share-dir` and/or
> > `find-user-share-dir`, adding a 'share mode to `define-runtime-path`
> > would make it possible for `raco distribute` to find and carry along a
> > directory/file when it's present, the same as 'so mode does.
>
> Added.
>

Wow, that was fast. Thanks!

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxxJKhaVzgG68dA5X2Pas8W5dR8VMG_H5_KNuV-Pe9nOug%40mail.gmail.com.


Re: [racket-users] Re: raco distribute and runtime paths, conditioned on whether a package was installed at compile time

2019-11-12 Thread Jon Zeppieri
On Tue, Nov 12, 2019 at 2:09 PM Matthew Flatt  wrote:
>
> I'd say the problem is that "info.rkt" and `find-relevant-directories`
> are set up as Racket-installation concepts. They're not made to play
> well with standalone applications.
>
> The most similar concept that plays well with standard applications is
> libraries in the Racket "lib" directory. Having packages that supply
> timezone information install the timezone files to Racket's "lib" (in
> the same way that a package like "db-win32-x86_64" installs a library)
> might be a better approach in the long run.
>
> If I understand, these files would make more sense in a "share"
> directory than in the "lib" directory. If that distinction seems
> important, we could add a 'share mode to `define-runtime-path` that is
> similar to 'lib mode.
>
>
> I think your solution so far, which relies on compile-time checks, will
> not work right with packages that are distributed in "built" form. That
> creates a problem, in turn, for building a Racket distribution.
>

I hadn't thought of built packages, but, yes, that sounds like a problem.

I like the idea of installing the data to a "share" directory. I see
that the `info.rkt` file for a collection has a `copy-shared-files`
key. In my case, both the `tzinfo` package and the `tzdata` package
contribute to the `tzinfo` collection. So, two questions: (1) Would it
work just to add this to the collection-level `info.rkt` in the
`tzdata` package? (2) How do I locate these files after they're
copied? Is this what the (notional) 'share mode for
`define-runtime-path` would do?

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxz%3D6H1X0hTSXczu9_PeLEhr_JrOC4QdJJYhkBPFJ0ybTQ%40mail.gmail.com.


[racket-users] Re: raco distribute and runtime paths, conditioned on whether a package was installed at compile time

2019-11-10 Thread Jon Zeppieri
On Sun, Nov 10, 2019 at 7:38 PM Jon Zeppieri  wrote:
>
> On Sun, Nov 10, 2019 at 4:45 PM Jon Zeppieri  wrote:
> >
> > On Sun, Nov 10, 2019 at 3:26 PM Jon Zeppieri  wrote:
> > > =
> > > ;; If the tzdata package is installed, put its zoneinfo directory at
> > > ;; the head of the search path.
> > > (define-runtime-path-list tzdata-paths
> > >   (match (find-relevant-directories '(tzdata-zoneinfo-module-path))
> > > [(cons info-dir _)
> > >  (define path ((get-info/full info-dir) 'tzdata-zoneinfo-module-path))
> > >  (list path)]
> > > [_
> > >  null]))

I found a version that works, though I still wonder if there'a a
better approach:

=
;; If the tzdata package is installed, put its zoneinfo directory at
;; the head of the search path.
(define-syntax (detect-tzdata stx)
  (syntax-case stx ()
[(_)
 (match (find-relevant-directories '(tzdata-zoneinfo-module-path))
   [(cons info-dir _)
(let ([path ((get-info/full info-dir) 'tzdata-zoneinfo-module-path)])
  #`(begin
  (define-runtime-path tzdata-path '#,path)
  (current-zoneinfo-search-path
   (cons (simplify-path tzdata-path)
 (current-zoneinfo-search-path)]
   [_ #'(void)])]))

(detect-tzdata)

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxy%2BMebOuymzgupND-1G668-mquS5uWjbQbmYuV%3D7bc__Q%40mail.gmail.com.


[racket-users] Re: raco distribute and runtime paths, conditioned on whether a package was installed at compile time

2019-11-10 Thread Jon Zeppieri
On Sun, Nov 10, 2019 at 4:45 PM Jon Zeppieri  wrote:
>
> On Sun, Nov 10, 2019 at 3:26 PM Jon Zeppieri  wrote:
> > =
> > ;; If the tzdata package is installed, put its zoneinfo directory at
> > ;; the head of the search path.
> > (define-runtime-path-list tzdata-paths
> >   (match (find-relevant-directories '(tzdata-zoneinfo-module-path))
> > [(cons info-dir _)
> >  (define path ((get-info/full info-dir) 'tzdata-zoneinfo-module-path))
> >  (list path)]
> > [_
> >  null]))
>
> I also tried doing the getinfo stuff at expansion time (so, at phase
> 2, when the RHS of `define-runtime-path` is running at phase 1, and at
> phase 1 when it's running at phase 0 -- it does also run at phase 0,
> right?), but that didn't help.

And I just tried this, with no luck:

(define-runtime-path-list tzdata-paths
  (with-handlers ([exn:fail:filesystem:missing-module? (λ (_) null)])
(list
 (resolved-module-path-name
  ((current-module-name-resolver) '(lib "tzdata/zoneinfo"
"tzinfo") #f #f #f)

The files did show up in the raco distribute bundle, but apparently
the code can't find them, which suggests that the
current-module-name-resolver isn't set to look for them there.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxyiS7eE1zYEWM_8t%2BxEXUajn27OWLe%2BhfqjVeKTS5K4Ww%40mail.gmail.com.


[racket-users] Re: raco distribute and runtime paths, conditioned on whether a package was installed at compile time

2019-11-10 Thread Jon Zeppieri
On Sun, Nov 10, 2019 at 3:26 PM Jon Zeppieri  wrote:
> =
> ;; If the tzdata package is installed, put its zoneinfo directory at
> ;; the head of the search path.
> (define-runtime-path-list tzdata-paths
>   (match (find-relevant-directories '(tzdata-zoneinfo-module-path))
> [(cons info-dir _)
>  (define path ((get-info/full info-dir) 'tzdata-zoneinfo-module-path))
>  (list path)]
> [_
>  null]))

I also tried doing the getinfo stuff at expansion time (so, at phase
2, when the RHS of `define-runtime-path` is running at phase 1, and at
phase 1 when it's running at phase 0 -- it does also run at phase 0,
right?), but that didn't help.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwgwsPQPQZxJbuPMwk7C80buuPWSKesNwyG%2B7HRut3QRg%40mail.gmail.com.


Re: [racket-users] Efficient idiom for converting key-set of a hash-map into a hash-set

2019-10-25 Thread Jon Zeppieri
Oh -- forgot to mention: if you're using an immutable hash, then
`in-immutable-hash-keys` is significantly faster than `in-hash-keys`.
I mean:

(for/set ([k (in-immutable-hash-keys h)]) k)


On Fri, Oct 25, 2019 at 4:37 PM Jon Zeppieri  wrote:
>
> From a little test I just ran, building a set of hash keys, using a
> hash with 100,000 k/v pairs and generating the key set 100 times each:
>
> "list->set"
> cpu time: 3147 real time: 3148 gc time: 1137
>
> "apply"
> cpu time: 3205 real time: 3206 gc time: 1146
>
> "in-hash"
> cpu time: 2791 real time: 2791 gc time: 974
>
> "in-hash-keys"
> cpu time: 2748 real time: 2749 gc time: 981
>
> On Fri, Oct 25, 2019 at 4:27 PM Stephen Chang  wrote:
> >
> > I don't know of a more efficient way to convert, but depending on what
> > operations you want, you might be able to compute it directly on the
> > hash, e.g., see hash-has-key?, hash-keys-subset?, hash-union, etc. (I
> > didnt know about some of the functions until recently.)
> >
> > On Fri, Oct 25, 2019 at 4:21 PM Sorawee Porncharoenwase
> >  wrote:
> > >
> > > It also might be worth trying `(for/set ([(k v) (in-hash h)]) k)`.
> > >
> > > On Fri, Oct 25, 2019 at 1:19 PM David Storrs  
> > > wrote:
> > >>
> > >> On Fri, Oct 25, 2019 at 10:28 AM Thomas Dickerson
> > >>  wrote:
> > >> >
> > >> > For reasons that are unclear to me, hash-keys and dict-keys both 
> > >> > return a list? instead of a set? (frankly, this seems like a bug in 
> > >> > the API...).
> > >> >
> > >> > Is there a something I can do that's more efficient than just calling 
> > >> > list->set?
> > >>
> > >> You could do   '(apply set list-of-keys)', although I'm not sure if
> > >> that's more efficient or not.  You'd need to benchmark it.
> > >>
> > >>
> > >> >
> > >> > --
> > >> > 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+unsubscr...@googlegroups.com.
> > >> > To view this discussion on the web visit 
> > >> > https://groups.google.com/d/msgid/racket-users/36eb8bd7-45eb-4ebb-be30-ebdfd89023fe%40googlegroups.com.
> > >>
> > >> --
> > >> 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+unsubscr...@googlegroups.com.
> > >> To view this discussion on the web visit 
> > >> https://groups.google.com/d/msgid/racket-users/CAE8gKodHgEeqffTCCSKDGP26jRt9oYmi42U0Vu%2BMyH6c2TQ5yw%40mail.gmail.com.
> > >
> > > --
> > > 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+unsubscr...@googlegroups.com.
> > > To view this discussion on the web visit 
> > > https://groups.google.com/d/msgid/racket-users/CADcuegvk8wqkJsdJNqkQXSHi5FgYGZ4afRODYoZD8FnYmOcxVg%40mail.gmail.com.
> >
> > --
> > 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+unsubscr...@googlegroups.com.
> > To view this discussion on the web visit 
> > https://groups.google.com/d/msgid/racket-users/CAFfiA1JXu_rEOP3V7vYO8oLW%2BfgOJrjK9%3DxXhr-WRYNvmVr6fQ%40mail.gmail.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxx%3DgqvtfZiPPiPmZFxA93brAomWukssCg%2BhfKQHsh%2Bcmg%40mail.gmail.com.


Re: [racket-users] Efficient idiom for converting key-set of a hash-map into a hash-set

2019-10-25 Thread Jon Zeppieri
>From a little test I just ran, building a set of hash keys, using a
hash with 100,000 k/v pairs and generating the key set 100 times each:

"list->set"
cpu time: 3147 real time: 3148 gc time: 1137

"apply"
cpu time: 3205 real time: 3206 gc time: 1146

"in-hash"
cpu time: 2791 real time: 2791 gc time: 974

"in-hash-keys"
cpu time: 2748 real time: 2749 gc time: 981

On Fri, Oct 25, 2019 at 4:27 PM Stephen Chang  wrote:
>
> I don't know of a more efficient way to convert, but depending on what
> operations you want, you might be able to compute it directly on the
> hash, e.g., see hash-has-key?, hash-keys-subset?, hash-union, etc. (I
> didnt know about some of the functions until recently.)
>
> On Fri, Oct 25, 2019 at 4:21 PM Sorawee Porncharoenwase
>  wrote:
> >
> > It also might be worth trying `(for/set ([(k v) (in-hash h)]) k)`.
> >
> > On Fri, Oct 25, 2019 at 1:19 PM David Storrs  wrote:
> >>
> >> On Fri, Oct 25, 2019 at 10:28 AM Thomas Dickerson
> >>  wrote:
> >> >
> >> > For reasons that are unclear to me, hash-keys and dict-keys both return 
> >> > a list? instead of a set? (frankly, this seems like a bug in the API...).
> >> >
> >> > Is there a something I can do that's more efficient than just calling 
> >> > list->set?
> >>
> >> You could do   '(apply set list-of-keys)', although I'm not sure if
> >> that's more efficient or not.  You'd need to benchmark it.
> >>
> >>
> >> >
> >> > --
> >> > 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+unsubscr...@googlegroups.com.
> >> > To view this discussion on the web visit 
> >> > https://groups.google.com/d/msgid/racket-users/36eb8bd7-45eb-4ebb-be30-ebdfd89023fe%40googlegroups.com.
> >>
> >> --
> >> 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+unsubscr...@googlegroups.com.
> >> To view this discussion on the web visit 
> >> https://groups.google.com/d/msgid/racket-users/CAE8gKodHgEeqffTCCSKDGP26jRt9oYmi42U0Vu%2BMyH6c2TQ5yw%40mail.gmail.com.
> >
> > --
> > 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+unsubscr...@googlegroups.com.
> > To view this discussion on the web visit 
> > https://groups.google.com/d/msgid/racket-users/CADcuegvk8wqkJsdJNqkQXSHi5FgYGZ4afRODYoZD8FnYmOcxVg%40mail.gmail.com.
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/CAFfiA1JXu_rEOP3V7vYO8oLW%2BfgOJrjK9%3DxXhr-WRYNvmVr6fQ%40mail.gmail.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzn5hDpp6tG2m7x_Z7FNFweQLOV3NjM5C_qGSj1zzkkKg%40mail.gmail.com.


Re: [racket-users] Would it help to call racket2 something else?

2019-08-28 Thread Jon Zeppieri
On Wed, Aug 28, 2019 at 11:43 PM Sage Gerard  wrote:
>
> Why is the name Racket2 so important, anyway?

It isn't. It's been mentioned several times that "Racket2" is
currently just a placeholder for whatever it ends up being called.

https://github.com/racket/racket2-rfcs/issues/111#issuecomment-523044004

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxyvbmWizb76xTQWsAAKpiVDDcPV9x-1hSLjUVu1A5MCyQ%40mail.gmail.com.


Re: [racket-users] (curry map string->number) in Typed Racket

2019-08-28 Thread Jon Zeppieri
On Wed, Aug 28, 2019 at 9:58 AM Štěpán Němec  wrote:
>
> On Wed, 28 Aug 2019 09:23:03 -0400
> Jon Zeppieri wrote:
>
> [...]
>
> >> Does that mean that for higher-order function parameters, inst expects
> >> only the return type signature, not that of the function itself?
> >
> > The main point here is that `inst` needs substitutions for the type
> > _variables_, not for the types of the function arguments.
>
> Oh, _now_ it makes sense! I see now that I really misunderstood even the
> example in the reference entry for `inst`: I took "(inst cons Integer
> Integer)" to mean "two Integer args" (which of course would only account
> for the (Pairof a b) case and doesn't make sense in the context) instead
> of "two Integer type variables".
>
> Thank you for the detailed explanation!


Glad to help. I don't know if you're familiar with System F, but if
you are, then you can think of `inst` as function application for
capital lambda (Λ) functions (functions that map types to terms). So,
a simplified version of map would look something like this (if Typed
Racket had explicit Λ functions):

(define map
  (Λ (c a)
(λ ([fn : (-> a c)]
 [lst: (Listof a)])
  ...)))

So, when you do `(inst map (U Complex False) String)`, you're applying
the outer Λ function, so that `c` and `a` get replaced in the body of
the function by `(U Complex False)` and `String`, respectively, and
you end up with:

(λ ([fn : (-> String (U Complex False))]
 [lst: (Listof String)])
  ...)

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzCYi58qMh1%3DZDhk6_marB_5JD_10do9FHOnGcA5RerjQ%40mail.gmail.com.


Re: [racket-users] (curry map string->number) in Typed Racket

2019-08-28 Thread Jon Zeppieri
On Wed, Aug 28, 2019 at 5:59 AM Štěpán Němec  wrote:
>
> On Thu, 22 Aug 2019 16:40:03 -0400
> Jon Zeppieri wrote:
>
> > (curry (inst map (U Complex False) String)
> >  string->number)
> >
> > ... typechecks, but in your expression, you're going to need to handle
> > the possibility that the pattern variables in `list-rest` pattern are
> > #f.
>
> Many thanks for the help. I find it quite confusing, though: I'd expect
> something like "(inst map (-> String (U Complex False)) (Listof String))",
> which apparently means something else...

Let's look at the type of `map`:

> map
- : (All (c a b ...)
  (case->
   (-> (-> a c) (Pairof a (Listof a)) (Pairof c (Listof c)))
   (-> (-> a b ... b c) (Listof a) (Listof b) ... b (Listof c

We're only interested in the two-argument case (though we do want to
admit empty lists) so we can treat that as if it were:

(All (c a) (-> (-> a c) (Listof a) (Listof c)))  [*]

There are two type variables to instantiate: c and a, and they need to
be instantiated in that order -- in the order they are bound by the
universal quantifier (`All`). The first argument to `map` is a
function of type (-> a c). In our case, that function will be
`string->number`, so now we need to know the type of `string->number`:

> string->number
- : (->* (String) (Number) (U Complex False))

It has an optional argument of type Number, but we don't need that, so
we're going to ignore it and treat this as if it were simply:

(-> String (U Complex False))

Remember, we were looking for a function of type:
 (-> a c)
and we found one of type:
 (-> String (U Complex False))

That means that `a` will be instantiated by `String` and `c` will be
instantiated by `(U Complex False)`. But recall the order that the
variables are bound by the universal quantifier: (All (c a) ...). So
we need to do:
 (inst map  ), which is:
 (inst map (U Complex False) String)

>
> Does that mean that for higher-order function parameters, inst expects
> only the return type signature, not that of the function itself?

The main point here is that `inst` needs substitutions for the type
_variables_, not for the types of the function arguments.

> But what about the String instead of (Listof String)? Or is this some kind
> of special case for functions like map? Is it documented somewhere?

This is a good illustration of what I just wrote: the type for `map`
that we wrote above requires a `(Listof a)`. Our job is to instantiate
the variable `a`. The `Listof` part is already there.

>
> And more generally, could you recommend any good learning resources (or
> good non-trivial code examples) of Typed Racket usage? I have read the
> guide and consulted the reference, but keep hitting the wall...

I'm afraid I can't help you with examples, but I bet some other people
on this list can.

- Jon

[*] The cases in the type of `map` are a bit confusing because, at
first glance, it looks like the first case is for the two-argument
version of `map`, whereas the second is for the vararg version. But
really the first version is for the two-argument version that is given
a non-empty list as the second argument (and therefore also returns a
non-empty list).

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwFSZSXHrhSWjhyaRZa6c%2BtsQK8E%3D1tH56C4K%3D8H71nPA%40mail.gmail.com.


Re: [racket-users] (curry map string->number) in Typed Racket

2019-08-22 Thread Jon Zeppieri
(curry (inst map (U Complex False) String)
 string->number)

... typechecks, but in your expression, you're going to need to handle
the possibility that the pattern variables in `list-rest` pattern are
#f.

- Jon

On Thu, Aug 22, 2019 at 4:15 PM Štěpán Němec  wrote:
>
>
> I have a hard time persuading Typed Racket to accept the expression
> "(curry map string->number)". No amount of type annotations or added
> `inst`s (as recommended by the guide[1]) I could come up with seem to
> help.
>
> Is there a way to make it work?
>
> [1] 
> https://docs.racket-lang.org/ts-guide/caveats.html#%28part._.Type_inference_for_polymorphic_functions%29
>
> Here's an example with a bit more context (solely for illustration
> purposes; I couldn't make the simple expression above work even
> isolated):
>
> (match-let ([(pregexp "#\\d+ +@ +(\\d+),(\\d+): +(\\d+)x(\\d+)"
>   (list-rest _ (app (curry map string->number)
> (list x y dx dy
>  "#1299 @ 414,871: 29x11"])
>   x)
>
> Thank you,
>
>   Štěpán
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/8736hths88.fsf%40gmail.com.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwOSK%3DAg0tw%3DtQgvZ9sRrnXt_J7YSz12V1wvLYRusfOzQ%40mail.gmail.com.


Re: [racket-users] Seeking good benchmark code for immutable hash and hash set usage

2019-08-22 Thread Jon Zeppieri
Thanks Ben! - Jon

On Wed, Aug 21, 2019 at 10:04 PM Ben Greenman
 wrote:
>
> A few of the GTP benchmarks [1] use immutable hashes. Here's a link
> with the ones that look most interesting:
>
> http://ccs.neu.edu/home/types/tmp/gtp-hash.tar.gz
>
>
> And here's a small (untyped) program that uses code from the tr-pfds
> library to make a trie:
>
> http://ccs.neu.edu/home/types/tmp/trie.tar.gz
>
>
> Redex and the graph library might be good places to look for other
> examples. I know graph uses lots of hashes internally, and I bet Redex
> does too.
>
> [1] https://github.com/bennn/gtp-benchmarks
>
> On 8/14/19, Jon Zeppieri  wrote:
> > Hello Racketeers,
> >
> > I'm looking for examples of code that would make good benchmarks for
> > evaluating the performance of immutable hashes.
> >
> > Some background:
> > Immutable hashes used to be implemented in Racket as red-black trees.
> > That was changed to hash array mapped tries (HAMTs) a number of years
> > back. In Racket CS, the current implementation is a Patricia trie.
> > That choice was based largely on the fact that it performed
> > significantly faster on the hash demo benchmarks[1] that any of the
> > HAMT variants I tested against. In particular, the write performance
> > of the HAMTs seemed especially poor.
> >
> > However, on some real-world code[2] I recently had occasion to test, a
> > HAMT consistently performs better than the Patricia trie, _especially_
> > on writes, which makes me think I put entirely too much weight on the
> > hash demo benchmark.
> >
> > So I'm looking for more realistic cases to use for benchmarking. If
> > you have a Racket application or library that makes heavy use of
> > immutable hashes or hash sets (from the racket/set module), please let
> > me know.
> >
> > Thanks,
> > Jon
> >
> > [1] https://github.com/racket/racket/blob/master/racket/src/cs/demo/hash.ss
> > I also tried to use the expander demo as a benchmark, but the timings
> > weren't significantly different with different hash implementations.
> >
> > [2] https://github.com/racket/racket/pull/2766#issuecomment-520173585
> > Well, it's a lot closer to real-world code than the hash demo.
> >
> > --
> > 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+unsubscr...@googlegroups.com.
> > To view this discussion on the web visit
> > https://groups.google.com/d/msgid/racket-users/CAKfDxxwjPcWewzo2X5uXGH06Ud1hjURNuKFW59duXrZq4-7tWQ%40mail.gmail.com.
> >

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxxYbOqjpy2GsLtumrK9q7vcfv_42c%3DR%3DAJXBO%2BhbJ%2BnUQ%40mail.gmail.com.


Re: [racket-users] Re: The case, and a proposal, for elegant syntax in #lang racket2

2019-08-21 Thread Jon Zeppieri
On Wed, Aug 21, 2019 at 2:43 PM George Neuner  wrote:
>
>
> On 8/21/2019 1:13 PM, Gustavo Massaccesi wrote:
> > The expander in racket adds something equivalent to
> > [else (void)]
> > if there is no else clause. (Try an example with the Macro Stepper.)
> > So an explicit else clause would not change the speed of the programs.
> >
> > In some cases the compiler can prove that the else part is not
> > necessary and drop it, Also, I think that the compiler in RacketCS can
> > notice that it has no side effects and also drop it if the result is
> > ignored (but I'm not 100% sure).
>
> Yes.  But in most cases, it is impossible to prove that the 'else' is
> unnecessary.

Yes, but this is why `else` doesn't slow anything down. Unless the
compiler can prove that it's unnecessary, an `else` clause going to be
there whether you write it explicitly or not, which is exactly what
Gustavo wrote above.


> And as I mentioned in my reply to Hendrick, 'cond' is
> pretty simple, but an 'else' - implicit or explicit - can screw up
> optimizing tests in a 'case'.
>

Racket's `case` is an implementation of this approach:
http://scheme2006.cs.uchicago.edu/07-clinger.pdf

It is not significantly complicated by `else`. And that approach was
created in the context of Scheme, which leaves the return value
unspecified when none of the tests are successful. That seems like it
should offer more opportunities for optimization, but I don't think
this approach is any less efficient when the unsuccessful result is
specified as # (as it is in Racket) than when it is not.

- Jon

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxxCMFHoC1%2B14VosKdeqOeg-dKc%2B3_nH-hjMf2JWjfxXOA%40mail.gmail.com.


[racket-users] Seeking good benchmark code for immutable hash and hash set usage

2019-08-14 Thread Jon Zeppieri
Hello Racketeers,

I'm looking for examples of code that would make good benchmarks for
evaluating the performance of immutable hashes.

Some background:
Immutable hashes used to be implemented in Racket as red-black trees.
That was changed to hash array mapped tries (HAMTs) a number of years
back. In Racket CS, the current implementation is a Patricia trie.
That choice was based largely on the fact that it performed
significantly faster on the hash demo benchmarks[1] that any of the
HAMT variants I tested against. In particular, the write performance
of the HAMTs seemed especially poor.

However, on some real-world code[2] I recently had occasion to test, a
HAMT consistently performs better than the Patricia trie, _especially_
on writes, which makes me think I put entirely too much weight on the
hash demo benchmark.

So I'm looking for more realistic cases to use for benchmarking. If
you have a Racket application or library that makes heavy use of
immutable hashes or hash sets (from the racket/set module), please let
me know.

Thanks,
Jon

[1] https://github.com/racket/racket/blob/master/racket/src/cs/demo/hash.ss
I also tried to use the expander demo as a benchmark, but the timings
weren't significantly different with different hash implementations.

[2] https://github.com/racket/racket/pull/2766#issuecomment-520173585
Well, it's a lot closer to real-world code than the hash demo.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwjPcWewzo2X5uXGH06Ud1hjURNuKFW59duXrZq4-7tWQ%40mail.gmail.com.


Re: [racket-users] finding the expander at run-time

2019-08-04 Thread Jon Zeppieri
On Sun, Aug 4, 2019 at 2:40 PM Jesse Alama  wrote:
> [...]
>
> In secret.rkt I've essentially got this:
>
>   (define program (parse path))
>   (parameterize ([current-namespace (make-base-empty-namespace)])
>  (namespace-require '(file "expander.rkt"))
>  (eval program))
>

I thought I knew the solution, but when I tried it, it didn't work.

I thought you needed to produce a runtime module path for the module
that you're `namespace-require`-ing:

   (define-runtime-module-path-index expander-path expander-path "expander.rkt")

... and then use that in the `namespace-require`. But when I produce
an executable and run it, I always get a "require: unknown module"
error. (Also, it wasn't clear to me if this is supposed to work unless
you also use `raco distribute`, so I tried that. Same problem.)

So I'm also stumped.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxyk7omp6AzGijv0R54ZnFPzy7MqfETNg3wZmq8yHN1uiA%40mail.gmail.com.


Re: [racket-users] How to implement a hash function for different types?

2019-08-03 Thread Jon Zeppieri
On Sat, Aug 3, 2019 at 1:35 AM Jon Zeppieri  wrote:
>
> On Sat, Aug 3, 2019 at 12:52 AM Jesse Wang  wrote:
> >
> > If I want to turn the hash code into array index in a hash table, do I need 
> > to
> > apply another uniform hash function such as md5 on the result of 
> > equal-hash-code?
> >
>
> That wouldn't accomplish anything. [...]

Sorry! My response assumed that you're concerned with the hash codes
themselves colliding, but of course you're concerned about the codes
modulo the length of the table (or bit-masked) colliding. (I've been
thinking too much about immutable hashes lately, which aren't actually
hash tables.)

So, yes, applying a cryptographic hash function to the result could
help with this case, but at some point you need to consider whether
the improvement is worth the cost. Cryptographic hash functions are
usually a lot more expensive to compute than the hash functions
commonly used in hash tables.

---

I just saw your response. If you're concerned about performance, you
should try it out and measure. Collisions certainly do slow down hash
tables, but so do expensive hash functions. It's a trade-off.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxwm2PqGKu-PWyd5TtqiCpJy%2BWVeAimAUkOU3dtJqMOKNg%40mail.gmail.com.


Re: [racket-users] How to implement a hash function for different types?

2019-08-02 Thread Jon Zeppieri
On Sat, Aug 3, 2019 at 12:52 AM Jesse Wang  wrote:
>
> If I want to turn the hash code into array index in a hash table, do I need to
> apply another uniform hash function such as md5 on the result of 
> equal-hash-code?
>

That wouldn't accomplish anything. The defining feature of a function
is that the output depends solely on the input. Applying the same
function to colliding hash codes will get you more colliding hash
codes, only at a higher cost.

If you're going to implement your own hash tables instead of using the
ones that Racket provides, you can use whatever hash function you
want, but in that case you want to start with the key itself, not with
the result of Racket's hash function. Hash functions, by their very
nature, tend to discard information. If you start with the result of
Racket's hash functions, you're not going to be able to do better than
them.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzKbh%3D80P7D10b-kxzky4QzkxU6WR_bR7jZDcSr_8dMLg%40mail.gmail.com.


Re: [racket-users] How to implement a hash function for different types?

2019-08-02 Thread Jon Zeppieri
On Fri, Aug 2, 2019 at 9:37 PM Justin Zamora  wrote:
>
> Racket doesn't implement hash tables using a hash function. If I
> recall correctly, it uses b-trees as the representation for a hash
> table.  The Racket reference states that "Immutable hash tables
> actually provide O(log N) access and update. Since N is limited by the
> address space so that log N is limited to less than 30 or 62
> (depending on the platform), log N can be treated reasonably as a
> constant." See. https://docs.racket-lang.org/reference/hashtables.html
>
> Justin
>
> On Fri, Aug 2, 2019 at 9:22 PM Jesse Wang  wrote:
> >
> > Racket allows different types of keys in a single hash, so there must be a 
> > hash function that works for different types(different primitive types), I 
> > wonder how Racket implements this under the hood.
> > Also, If I want to implement a hash table which allows different types of 
> > keys, how can I implement such a hash function in Racket?
> >
> > Thanks!
> >
> > --


- Racket has both mutable and immutable hashes. Both use hash
functions -- both use the same hash functions, but these hash
functions take into account what kind of data they're called on. See
https://github.com/racket/racket/blob/master/racket/src/cs/rumble/hash-code.ss.
- Immutable hashes are implemented as hash array-mapped tries in
Racket "classic" and Patricia tries in Racket-on-Chez.
- There are equal?-, eqv?-, and eq?-based hashes (both mutable and immutable).
- Each equivalence relation has a corresponding hash function.
(Actually equal? hash two corresponding hash functions:
equal-hash-code? and equal-secondary-hash-code?.)
- Struct types can provide their own implementations of equal?,
equal-hash-code, and equal-secondary-hash-code (see gen:equal+hash).
- So: the built-in hashes can be used with new data types.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxziv4rx0Rpb1yo%3D_ssTBWrrFh0gOGvDVxVsO_fQ-db6Ng%40mail.gmail.com.


Re: [racket-users] file-position does not extend file as expected

2019-06-24 Thread Jon Zeppieri
On Mon, Jun 24, 2019 at 4:51 PM Jon Zeppieri  wrote:
>
> `lseek` docs say:
>
> > The lseek() function shall allow the file offset to be set beyond the end 
> > of the existing data in the file. If data is later written at this point, 
> > subsequent reads of data in the gap shall return bytes with the value 0 
> > until data is actually written into the gap.
>

And the Windows call `SetFilePosition` is similar:

> It is not an error to set a file pointer to a position beyond the end of the 
> file. The size of the file does not increase until you call the SetEndOfFile, 
> WriteFile, or WriteFileEx function. A write operation increases the size of 
> the file to the file pointer position plus the size of the buffer written, 
> which results in the intervening bytes uninitialized.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxzx%3DiL-JQkJBx_SC%2BF05kG%2BUMW%2Bn%2BNWfsaDorvHcCdzkw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] file-position does not extend file as expected

2019-06-24 Thread Jon Zeppieri
I *think* that the docs are wrong here. `file-position` maps onto
`lseek` on posix systems (pretty sure about this after a quick perusal
of the code) and `lseek` docs say:

> The lseek() function shall allow the file offset to be set beyond the end of 
> the existing data in the file. If data is later written at this point, 
> subsequent reads of data in the gap shall return bytes with the value 0 until 
> data is actually written into the gap.

So the file isn't really extended until you write something at that
position. But I'm sure Matthew can dive a definitive answer here.

- Jon




On Mon, Jun 24, 2019 at 4:31 PM David Storrs  wrote:
>
> Consider the following test script:
>
> #lang racket
>
> (define (say . args) (displayln (apply ~a args)))
> (define the-path "./test-file")
> (when (file-exists? the-path)  (delete-file the-path))
> (say "before open, file exists?: " (file-exists? the-path))
>
> (let ([the-port (open-output-file the-path #:mode 'binary #:exists 'append)])
>   (say "after open, file exists?: " (file-exists? the-path))
>   (say "file size, position: " (file-size the-path) ", " (file-position 
> the-port))
>   (file-position the-port 1000); should extend the file and fill the 
> intervening space with 0
>   (say "file size, position: " (file-size the-path) ", " (file-position 
> the-port))
>   (flush-output the-port) ; ensure that the filling 0s have been written, 
> just to be sure
>   (say "file size, position: " (file-size the-path) ", " (file-position 
> the-port)))
>
>
> The output is:
>
> before open, file exists?: #f
> after open, file exists?: #t
> file size, position: 0, 0
> file size, position: 0, 1000
> file size, position: 0, 1000
>
> The file on disk is in fact 0B long.  The docs for file-position 
> (https://docs.racket-lang.org/reference/port-buffers.html#%28def._%28%28quote._~23~25kernel%29._file-position%29%29)
>  include the following:
>
> "When file-position sets the position pos beyond the current size of an 
> output file or (byte) string, the file/string is enlarged to size pos and the 
> new region is filled with 0 bytes. If pos is beyond the end of an input file 
> or (byte) string, then reading thereafter returns eof without changing the 
> port’s position."
>
> Given the above, I was expecting the file to end up being 1000 bytes.  I'm 
> using Racket 7.1 on OSX 10.11; is this an OS issue or am I misunderstanding 
> something about Racket?
>
> --
> 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+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/CAE8gKofKWtAKU4ZQk6ai-ydZx7WmY8%3D1GwDUFbW15BpxUSQ1qw%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxw0cj%3D2EJBN2gjRjCGiYELrhhMxAz4-tuB%3DuoDX-phoBA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Are function parameters copy on write?

2019-06-06 Thread Jon Zeppieri
On Thu, Jun 6, 2019 at 12:00 PM David Storrs  wrote:

> My understanding is that Racket is call by value, not call by reference.
> My application will often be passing around large-ish byte strings; will
> they be copied every time I pass them, or will the interpreter use
> copy-on-write?
>


"call-by-value" is used in two very different ways. Racket is call-by-value
in the sense that all arguments to functions need to be evaluated before
the function body is evaluated. This kind of "call-by-value" is
distinguished from other evaluation strategies, like call-by-name or
call-by-need.

The other sense of the term -- and the one you're asking about -- has to do
with whether arguments are copied from caller to callee. I find the terms
"call-by-value" and "call-by-reference" in this context to be pretty
confusing. (If the function argument in question is a mutable byte-string,
why wouldn't passing it "by-value" imply that you pass the very same
mutable byte-string, rather than making a copy of it?) At any rate, Racket
does not copy arguments on function calls (except insofar as the copy is
indistinguishable from the original -- as with a fixnum, for example).

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAKfDxxx8TxKvuASFRgNd8A205LvdEFzggG-BN7o8ocRN5pk%2BvQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] db module + SQLite driver + 'ON CONFLICT' = syntax error

2019-04-18 Thread Jon Zeppieri
It might well be the SQLlite version. This is a pretty new feature. It's
possible that the db library is using an older version than your CLI client.

- Jon


On Thu, Apr 18, 2019 at 4:03 PM David Storrs  wrote:

> I'm having trouble with using the the 'ON CONFLICT' clause with a SQLite
> database.  Example:
>
> > (query-exec db "drop table if exists peers")
> > (query-exec db "create table if not exists peers (name text)")
> > (query-exec db "INSERT INTO peers ( name ) VALUES ($1)" "hqwt")
> > (query-rows db "SELECT * FROM peers")
> '(#("hqwt"))
> > (query-exec db "INSERT INTO peers ( name ) VALUES ($1) ON CONFLICT DO
> NOTHING" "hqwt")
> ; query-exec: near "ON": syntax error
> ;   error code: 1
> ; [,bt for context]
>
> I thought maybe there was some issue with the column not being marked
> UNIQUE, so I did that.  No effect:
>
> > (query-exec db "drop table if exists peers")
> > (query-exec db "create table if not exists peers (name text UNIQUE)")
> > (query-exec db "INSERT INTO peers ( name ) VALUES ($1)" "hqwt")
> > (query-exec db "INSERT INTO peers ( name ) VALUES ($1)" "hqwt")
> ; query-exec: abort due to constraint violation
> ;   error code: 2067
> ;   SQL: "INSERT INTO peers ( name ) VALUES ($1)"
> ; [,bt for context]
> > (query-exec db "INSERT INTO peers ( name ) VALUES ($1) ON CONFLICT DO
> NOTHING" "hqwt")
> ; query-exec: near "ON": syntax error
> ;   error code: 1
> ; [,bt for context]
>
> I've been through the SQLite documentation on the INSERT statement
> multiple times, and that last statement sure looks syntactically valid to
> me.  Furthermore, it works fine if I use it in the OSX 10.11.6 sqlite3 CLI
> client.
>
> What am I missing?
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] printing decimals

2019-03-15 Thread Jon Zeppieri
https://docs.racket-lang.org/reference/strings.html?q=~r#%28def._%28%28lib._racket%2Fformat..rkt%29._~7er%29%29

On Fri, Mar 15, 2019 at 1:57 PM  wrote:

> Hi all,
>
> I've been looking through the docs for a way to print decimals to a
> defined precision.
>
> I can get close to what I want using something like ~a and giving it a set
> width without having to build a function to do so. I mean I can build a
> function to do as its just a bit of string manip but it feels really odd
> that there doesn't seem to be a built in way to do so even though we try to
> keep all the decimals in fractional notation to maintain precision as long
> as possible in racket.
>
> any ideas anyone or am I just being blind and its right there in the docs
> somewhere?
>
> thanks,
> Scott
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] json, performance, racket cs, puzzlement, etc.

2019-03-03 Thread Jon Zeppieri
On Sat, Mar 2, 2019 at 3:38 PM Matthew Flatt  wrote:

>
> That's a big difference between Racket and Racket CS. My initial
> thought was that the program must have a lot of indirect function
> calls, and Racket CS is faster at those... but not by such a big
> factor. You don't use `call/cc`, right?
>

No call/cc. These are just normal functions that get tail-called by the
parsers.

There definitely are a lot of indirect function calls. I've tried using
`define-inline` in a bunch of places to mitigate the effect. Doesn't seem
to help.


>
> A difference of 60ms/140ms versus 3.3s sounds algorithmic, as opposed
> to something about the representation or cost of functions as
> continuations.
>
> How much memory does the program use, and how much of the run time is
> GC time?
>

How would you measure the former? Use a larger file and monitor the
process? Or is there a better way within racket? Start a thread that dumps
current-memory-use every so often?

GC accounts for a bit less than a tenth of the total time, which seems to
be on par with the parser in the json module.

I also just realized that I wasn't using profile with errortrace, even
though I thought I was. I do get much more information with errortrace on.
It does seem to confirm the hypothesis that a lot of time is spent in
unknown function calls. (Though I also wonder of errortrace is prohibiting
any inlining, which would turn many unknown calls into known ones.) Also, a
good amount of time is spent looping (`for` loops using `in-bytes`, but a
#:when that uses an unknown predicate).

- Jon

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


[racket-users] json, performance, racket cs, puzzlement, etc.

2019-03-02 Thread Jon Zeppieri
After the recent discussion on json parsing performance, I spent some time
doing a quick port of enough of attoparsec and aeson (haskell libraries
providing, respectively, byte-oriented parser combinators and json parsing)
to do some testing.

The result: really slow. (This is where the puzzlement comes in. I'll get
back to that in just a moment.) This 1MB sample file [
https://github.com/samoconnor/LazyJSON.jl/blob/master/test/ec2-2016-11-15.normal.json]
takes about 20s to parse on my machine using my aeson-alike library. By
contrast, the same file parses in roughly 160ms with the json module that
ships with racket.

So really, really slow.

Then I downloaded the most recent racket-cs build. My library parsed the
same file in about 3.3s. So an *enormous* improvement. (Caveat, I'm only
measuring runtime here, not compilation/expansion time.) Still, sadly, very
slow compared to the existing library.

So I tested the existing library on the file, under racket-cs. (Actually, I
think the version that came with this racket-cs build includes Matthew's
recent improvements, so it's not exactly quite the same parser.) It parsed
the file in 45-50ms.

That's a long-winded way of saying that:
- Racket CS provides a huge performance improvement to some programs.
- My parser is slw.

This is the part where I express puzzlement and ask for your help.

It's not obvious to me why my parser is so slow. The haskell library from
which it is unabashedly copied is known to be fast, and I don't think it
leans heavily on laziness anywhere. One quirk of its design: each parser is
passed a failure and a success continuation; they never return. So, on top
of all the normal function-upon-function layering that you get in any
parser combinator library, you get some extra here, since the continuations
are heap-allocated closures. Apparently, this was a big win for the
original library's performance [
http://www.serpentine.com/blog/2011/02/25/cps-is-great-cps-is-terrible/],
but maybe that doesn't work so well in racket.

I tried profiling. It was not very illuminating, and I suspect CPS is
getting in the way there, too. (It's hard to measure the time between
function call and return if there is no return.) Any clever ideas on how to
find out where all the time is being spent?

- Jon

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


Re: [racket-users] How do I get the username from a database handle?

2019-02-26 Thread Jon Zeppieri
On Tue, Feb 26, 2019 at 4:58 PM David Storrs  wrote:

> Given a database handle, I'd like to be able to ask it what user it's
> connected as.  Is there a way to do this?
>
>
I don't see anything in the `db` library's API to get this, but your
database probably allows you to do it in SQL (at the cost of a DB
round-trip, of course). E.g., in Postgres: `SELECT current_user`.

- Jon

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


Re: [racket-users] Cannot use case+else inside match+else

2019-02-25 Thread Jon Zeppieri
Previously on this program...

https://lists.racket-lang.org/dev/archive/2013-May/thread.html
[racket-dev] else clauses: possible change to match?



On Mon, Feb 25, 2019 at 10:59 PM Greg Hendershott 
wrote:

> Yep, I also spent a non-zero number of years not even realizing "else"
> wasn't a magic literal for match. And then remembering to use _
> instead, as Sorawee suggested.
>
>
> I think this shows why it's usually better for syntax to use
> #:keywords instead of literals? If cond and case used #:else, this
> wouldn't be a problem.
>
> (Racket inherited those from Scheme. But we don't have to follow that
> example in our own, new macros.)
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] Re: How do I get (system-tzid) to return the correct value?

2019-02-25 Thread Jon Zeppieri
On Mon, Feb 25, 2019 at 9:42 PM Brian Adkins  wrote:

> On Friday, February 22, 2019 at 4:00:11 PM UTC-5, Jon Zeppieri wrote:
>
> Thanks for the fix Jon. I'm still a relative Racket newbie - I'd like to
> be able to install your package from the new branch, but I'd also like to
> be able to go back to the way things are now. As far as I know, I didn't
> install tzinfo explicitly, so I expect maybe the gregor package has it as a
> dependency. If that's the case, will gregor just happily use the new
> package from your branch?
>

Yep, tzinfo is a dependency of gregor. That won't prevent you from updating
tzinfo in-place, however. You can install the version from the github
branch and test it out. (I already tested it locally, on OS X and on
Windows in a virtual machine, but it would be great to have a Ubuntu test,
as well.) If it works, I'll merge the changes, and then you should be able
to upgrade the package again to the new published version.

If you prefer not to install an unpublished version, that's fine too. I
feel confident enough to merge the PR as-is. (I know, at least, that it
works on OS X and Windows.)

- Jon

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


Re: [racket-users] performance, json

2019-02-22 Thread Jon Zeppieri
On a related (but not too related) note: is there an efficient way to skip
multiple bytes in an input stream? It looks like there are two choices:
  - You can read the bytes you want to skip, but that implies either
allocating a useless byte array or keeping one around for this very purpose.
  - You can use (I think?) port-commit-peeked, bit given the API, it seems
like that was designed with a particular (and more complicated) use in mind.


On Fri, Feb 22, 2019 at 3:35 PM Matthew Flatt  wrote:

> I think the bigger bottleneck is the main parsing loop, which uses
> `regexp-try-match` even more. Although `regexp-try-match` is
> convenient, it's much slower than using `peek-char` directly to check
> for one character. I'll experiment with improvements there.
>
> At 22 Feb 2019 13:36:20 -0500, "'John Clements' via Racket Users" wrote:
> > I’m not that surprised :).
> >
> > My guess is that our json reader could be sped up quite a bit. This
> looks like
> > the heart of the read-json implementation:
> >
> > (define (read-json* who i jsnull)
> >   ;; Follows the specification (eg, at json.org) -- no extensions.
> >   ;;
> >   (define (err fmt . args)
> > (define-values [l c p] (port-next-location i))
> > (raise-read-error (format "~a: ~a" who (apply format fmt args))
> >   (object-name i) l c p #f))
> >   (define (skip-whitespace) (regexp-match? #px#"^\\s*" i))
> >   ;;
> >   ;; Reading a string *could* have been nearly trivial using the racket
> >   ;; reader, except that it won't handle a "\/"...
> >   (define (read-string)
> > (define result (open-output-bytes))
> > (let loop ()
> >   (define esc
> > (let loop ()
> >   (define c (read-byte i))
> >   (cond
> > [(eof-object? c) (err "unterminated string")]
> > [(= c 34) #f]   ;; 34 = "
> > [(= c 92) (read-bytes 1 i)] ;; 92 = \
> > [else (write-byte c result) (loop)])))
> >   (cond
> > [(not esc) (bytes->string/utf-8 (get-output-bytes result))]
> > [(case esc
> >[(#"b") #"\b"]
> >[(#"n") #"\n"]
> >[(#"r") #"\r"]
> >[(#"f") #"\f"]
> >[(#"t") #"\t"]
> >[(#"\\") #"\\"]
> >[(#"\"") #"\""]
> >[(#"/") #"/"]
> >[else #f])
> >  => (λ (m) (write-bytes m result) (loop))]
> > [(equal? esc #"u")
> >  (let* ([e (or (regexp-try-match #px#"^[a-fA-F0-9]{4}" i)
> >(err "bad string \\u escape"))]
> > [e (string->number (bytes->string/utf-8 (car e)) 16)])
> >(define e*
> >  (if (<= #xD800 e #xDFFF)
> >  ;; it's the first part of a UTF-16 surrogate pair
> >  (let* ([e2 (or (regexp-try-match
> #px#"^u([a-fA-F0-9]{4})"
> > i)
> > (err "bad string \\u escape, ~a"
> >  "missing second half of a UTF16
> pair"))]
> > [e2 (string->number (bytes->string/utf-8 (cadr
> e2))
> > 16)])
> >(if (<= #xDC00 e2 #xDFFF)
> >(+ (arithmetic-shift (- e #xD800) 10) (- e2
> #xDC00)
> > #x1)
> >(err "bad string \\u escape, ~a"
> > "bad second half of a UTF16 pair")))
> >  e)) ; single \u escape
> >(write-string (string (integer->char e*)) result)
> >(loop))]
> > [else (err "bad string escape: \"~a\"" esc)])))
> >   ;;
> >   (define (read-list what end-rx read-one)
> > (skip-whitespace)
> > (if (regexp-try-match end-rx i)
> > '()
> > (let loop ([l (list (read-one))])
> >   (skip-whitespace)
> >   (cond [(regexp-try-match end-rx i) (reverse l)]
> > [(regexp-try-match #rx#"^," i) (loop (cons (read-one)
> l))]
> > [else (err "error while parsing a json ~a" what)]
> >   ;;
> >   (define (read-hash)
> > (define (read-pair)
> >   (define k (read-json))
> >   (unless (string? k) (err "non-string value used for json object
> key"))
> >   (skip-whitespace)
> >   (unless (regexp-try-match #rx#"^:" i)
> > (err "error while parsing a json object pair"))
> >   (list (string->symbol k) (read-json)))
> > (apply hasheq (apply append (read-list 'object #rx#"^}" read-pair
> >   ;;
> >   (define (read-json [top? #f])
> > (skip-whitespace)
> > (cond
> >   [(and top? (eof-object? (peek-char i))) eof]
> >   [(regexp-try-match #px#"^true\\b"  i) #t]
> >   [(regexp-try-match #px#"^false\\b" i) #f]
> >   [(regexp-try-match #px#"^null\\b"  i) jsnull]
> >   [(regexp-try-match
> > #rx#"^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?" i)
> >=> (λ (bs) (string->number (bytes->string/utf-8 (car bs]
> >   [(regexp-try-match #rx#"^[\"[{]" i)
> >=> (λ 

Re: [racket-users] Re: How do I get (system-tzid) to return the correct value?

2019-02-22 Thread Jon Zeppieri
On Fri, Feb 22, 2019 at 11:36 AM Brian Adkins  wrote:

>
> It seems that not short circuiting would be a good idea regardless of
> other changes. It's not urgent for me, because the code in question won't
> run late in the evening where the problem occurs.
>
>
I have a proposed fix, if you care (or anyone else cares) to take a look
and comment: https://github.com/97jaz/tzinfo/pull/7

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


Re: [racket-users] Re: How do I get (system-tzid) to return the correct value?

2019-02-22 Thread Jon Zeppieri
On Fri, Feb 22, 2019 at 11:22 AM Jon Zeppieri  wrote:

>
> - I could also abandon the symlink check altogether and always use the
> slow path, which checks for file _content_ identity between /etc/timezone
> and any file that names an IANA time zone in the zoneinfo tree.
>

Or. better, use file-or-directory-identity. (I didn't know this existed.)

- Jon

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


Re: [racket-users] Re: How do I get (system-tzid) to return the correct value?

2019-02-22 Thread Jon Zeppieri
On Fri, Feb 22, 2019 at 10:44 AM Brian Adkins  wrote:

>
> Yes, I think we found the problem:
>
> $ ls -l /etc/localtime
> lrwxrwxrwx 1 root root 36 Feb 21 21:45 /etc/localtime ->
> /usr/share/zoneinfo/America/New_York
> deploy@ip-172-31-10-34:~$ ls -l /usr/share/zoneinfo/America/New_York
> lrwxrwxrwx 1 root root 13 Jan  1 00:05
> /usr/share/zoneinfo/America/New_York -> ../posixrules
>
>
> $ racket
> Welcome to Racket v7.1.
> > (require racket/enter)
> > (require tzinfo/private/zoneinfo)
> > (enter! tzinfo/private/zoneinfo)
> /tzinfo/tzinfo/private/zoneinfo> (define zi (make-zoneinfo-source))
> /tzinfo/tzinfo/private/zoneinfo> (tzinfo-has-tzid? zi
> "America/New_York")
> #t
> /tzinfo/tzinfo/private/zoneinfo> (find-zoneinfo-directory
> default-zoneinfo-search-path)
> "/usr/share/zoneinfo"
> /tzinfo/tzinfo/private/zoneinfo> (detect-tzid/unix (zoneinfo-dir zi)
>
>  (find-zoneinfo-directory default-zoneinfo-search-path)
>
>  (tzinfo->all-tzids zi))
> "posixrules"
>
>
Well, that's one I haven't seen before -- a file that actually names a time
zone is a symlink to another file. (I see we're not the only people who
have run afoul of this [https://github.com/HowardHinnant/date/issues/252]).

We have a few options here.
- Simply putting the /etc/timezone check before the /etc/localtime check
would solve the problem for you, though not for systems that use
/etc/localtime as a symlink but do not use /etc/timezone.
- Similarly, not short-circuiting the various checks and only looking for
valid values after we've accumulated all the results of the tests would
work in your case, assuming that (tzid-from-/etc/timezone) returns the
right answer for you (which I assume it does).
- Changing the implementation of the /etc/localtime check to use
readlink(2) to follow the symlink a single step is an option, though it
wouldn't help if someone linked directly from /etc/localtime to posixrules.
That sounds like a crazy scenario, but I would have said that linking
America/New_York to posixrules is unlikely. (I'd expect it to be the other
way around.) I guess the more general approach would be to use readlink(2)
until we find a path that names a time zone.
- I could also abandon the symlink check altogether and always use the slow
path, which checks for file _content_ identity between /etc/timezone and
any file that names an IANA time zone in the zoneinfo tree.

(Of course, all of this would be unnecessary if the tzid were actually
somewhere _in_ the tzfile(5) format somewhere.)

If you need an immediate workaround, you can launch racket with the TZ
environment variable set to the contents of /etc/timezone. But I'll fix
this just as soon as I decide what the best approach is.


By the way (and this question is for everyone), am I right that readlink(2)
functionality isn't already in the Racket standard library anywhere? (I
don't know if it has an analogue on Windows.)

 - Jon

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


Re: [racket-users] Re: How do I get (system-tzid) to return the correct value?

2019-02-21 Thread Jon Zeppieri
I just realized that some of my instructions rely on DrRacket, and you
mentioned that this is on AWS, so you probably you're likely not running
that. The reason I suggested running the code in DrRacket is that it allows
you to work within a module, so that you're not restricted to calling only
provided functions. But you can do the same in the textual repl, I think,
using `enter!`.

- Jon

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


Re: [racket-users] Re: How do I get (system-tzid) to return the correct value?

2019-02-21 Thread Jon Zeppieri
On Thu, Feb 21, 2019 at 10:12 PM Brian Adkins  wrote:

> On Thursday, February 21, 2019 at 9:54:23 PM UTC-5, Jon Zeppieri wrote:
>>
>>
>>
>> On Thu, Feb 21, 2019 at 9:48 PM Brian Adkins  wrote:
>>
>>> On Thursday, February 21, 2019 at 9:35:58 PM UTC-5, Brian Adkins wrote:
>>>>
>>>> On Thursday, February 21, 2019 at 9:26:07 PM UTC-5, Brian Adkins wrote:
>>>>>
>>>>> I'm using the (today) function from the gregor library. It was
>>>>> returning tomorrow instead of today, so I thought the problem was the
>>>>> timezone on my Ubuntu server. I configured the timezone to be US/Eastern
>>>>> via: sudo dpkg-reconfigure tzdata
>>>>>
>>>>> Now the date command returns:  Thu Feb 21 21:23:43 EST 2019   as
>>>>> expected.
>>>>>
>>>>> Unfortunately, (system-tzid) returns:  "Etc/UTC"
>>>>>
>>>>> So, gregor's (today) still returns tomorrow (since it's so late).
>>>>>
>>>>> Anyone know how to get (system-tzid) to return the correct value on
>>>>> Ubuntu?
>>>>>
>>>>
>>>> Some more info:
>>>>
>>>> /etc/localtime is linked as:  localtime ->
>>>> /usr/share/zoneinfo/US/Eastern
>>>>
>>>
>>> I reinvoked sudo dpkg-reconfigure tzdata  and chose America/New_York
>>> instead of  US/Eastern, but I still get the default "Etc/UTC" from
>>> (system-tzid)
>>>
>>
>>
>> Huh. Could you do the following and tell me what you get?
>>
>> > (require tzinfo/private/generics)
>> > (require tzinfo/private/zoneinfo)
>> > (define zi (make-zoneinfo-source))
>> > (zoneinfo-dir zi)
>> "/usr/share/zoneinfo"
>> > (detect-system-tzid zi)
>> "America/New_York"
>>
>
> > (require tzinfo/private/generics)
> > (require tzinfo/private/zoneinfo)
> > (define zi (make-zoneinfo-source))
> > (zoneinfo-dir zi)
> "/usr/share/zoneinfo"
> > (detect-system-tzid zi)
> #f
>
> Also:
>
> $ ls -l /etc/localtime
> lrwxrwxrwx 1 root root 36 Feb 21 21:45 /etc/localtime ->
> /usr/share/zoneinfo/America/New_York
>
> $ cat /etc/timezone
> America/New_York
>
>

Thanks.

Okay, so first I figured that the problem was probably due to the weird way
that I try to discover the target of an /etc/timezone symlink. (Racket
doesn't provide that functionality, as far as I could tell at the time, and
I guess I wanted to avoid the FFI? Even though I used it for Windows? My
memory fails me.)

But, if that method fails, it also tries getting the value from
/etc/timezone, which you noted, is set correctly. And that method of
getting the timezone is really simple. It just reads the file. So... hmm.
Okay, let's do this exhaustively.

1. Verify that (system-type) is 'unix. (Just to make sure we check
everything.)

2. In DrRacket, in the definitions window, put the following:
```
#lang racket/base

(require tzinfo/private/zoneinfo)
```
3. Right click on `tzinfo/private/zoneinfo` and select "Open zoneinfo.rkt."

4. In the new DrRacket window that contains the source of zoneinfo.rkt,
click "Run."

5. Then, in the interaction pane, do:
> (define zi (make-zoneinfo-source))
> (tzinfo-has-tzid? zi "America/New_York")
#t

If this is #f, that would be bad, and you can stop right there.

6. Next:
> (find-zoneinfo-directory default-zoneinfo-search-path)
"/usr/share/zoneinfo"

If you don't get the same values for this, that would be odd.

7.
> (detect-tzid/unix (zoneinfo-dir zi)
(find-zoneinfo-directory default-zoneinfo-search-path)
(tzinfo->all-tzids zi))
"America/New_York"

I expect you'll either get #f here or else you'll get a string but it won't
be a valid IANA time zone name.

8. Near the top of zoneinfo.rkt, you'll see a require line for
"os/unix.rkt." Right click that and open the file. Run it.

9. In the interactions pane:
> (tzid-from-env)
#f

(If this isn't #f, and it also isn't an valid IANA time zone id, that would
be the problem.)

10.
> (tzid-from-/etc/timezone)
#f

Based on what you wrote above, I expect you to get "America/New_York" here.
(I get #f, but I'm on OS X.)

===

I think you'll have to get unexpected results from one of these, and that
should help us figure out the problem.
My best guess right now is that detect-tzid/unix will return a string that
isn't a valid IANA tzid. And that might be because you have the TZ
environment variable set.

Thank you for helping me track down this bug. If my guess is correct, I
need to make a slight change to the code.

(Summary: detect-tzid/unix tries a few different methods for determining
the system time zone, and it stops when any one of them is non-#f. But the
returned string is only validated against the list of IANA zones
afterwards, so if any of those methods returns a string that isn't a valid
time zone, it won't try any of the other methods.)

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


Re: [racket-users] Re: How do I get (system-tzid) to return the correct value?

2019-02-21 Thread Jon Zeppieri
On Thu, Feb 21, 2019 at 9:48 PM Brian Adkins  wrote:

> On Thursday, February 21, 2019 at 9:35:58 PM UTC-5, Brian Adkins wrote:
>>
>> On Thursday, February 21, 2019 at 9:26:07 PM UTC-5, Brian Adkins wrote:
>>>
>>> I'm using the (today) function from the gregor library. It was returning
>>> tomorrow instead of today, so I thought the problem was the timezone on my
>>> Ubuntu server. I configured the timezone to be US/Eastern via: sudo
>>> dpkg-reconfigure tzdata
>>>
>>> Now the date command returns:  Thu Feb 21 21:23:43 EST 2019   as
>>> expected.
>>>
>>> Unfortunately, (system-tzid) returns:  "Etc/UTC"
>>>
>>> So, gregor's (today) still returns tomorrow (since it's so late).
>>>
>>> Anyone know how to get (system-tzid) to return the correct value on
>>> Ubuntu?
>>>
>>
>> Some more info:
>>
>> /etc/localtime is linked as:  localtime -> /usr/share/zoneinfo/US/Eastern
>>
>
> I reinvoked sudo dpkg-reconfigure tzdata  and chose America/New_York
> instead of  US/Eastern, but I still get the default "Etc/UTC" from
> (system-tzid)
>


Huh. Could you do the following and tell me what you get?

> (require tzinfo/private/generics)
> (require tzinfo/private/zoneinfo)
> (define zi (make-zoneinfo-source))
> (zoneinfo-dir zi)
"/usr/share/zoneinfo"
> (detect-system-tzid zi)
"America/New_York"

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


Re: [racket-users] Help with generators from python land!

2019-02-20 Thread Jon Zeppieri
On Wed, Feb 20, 2019 at 9:14 PM Dave McDaniel 
wrote:

> Thanks Jon and Jen, This is a great!  I figured there must be a
> straightforward way to do this with a `for/hash` implementation.  I have
> not seen these 2 methods `in-hash` and `in-list` vs just using the hash or
> list without that sequence modifier.  Can you comment on what is going on
> with this `in-xxx` sequence modification?  The docs indicate that you get
> slightly better performance when using these with `for`, but its not clear
> why and in what situations you must use these modifiers rather than the
> underlying list or hash itself--is it always optional?
>

`in-hash` and `in-list` are optional, but, as you noted, they do make
iteration perform better.[*] This is because the various iterators can
generate better code if they know what kind of sequence they're dealing
with. If they don't know, they have to use generic sequence operations,
which are usually quite a lot less efficient. The difference is not slight.
(Do the docs say it is?)

That said, if you're only iterating over a small sequence, you won't notice
or care.

You can see the difference in generated code by using the Macro Stepper in
Dr. Racket. Write something like:
```
#lang racket/base

(define (fast-foo xs)
  (for/list ([x (in-list xs)])
x))

(define (slow-foo xs)
  (for/list ([x xs])
x))
```

Then click on the Macro Stepper button and then click "End" to see the
fully expanded source, and compare the two different versions.

[*] Rather, they make iteration perform better when they're used inside a
`for` loop. Outside of a `for`, they're just normal procedures. Inside,
they are syntax and direct code generation. You would _not_ get better
performance from:

(slow-foo (in-list my-list))
  than you would from
(slow-foo my-list)

==

However, it's not the case that the `in-` syntax is always
optional. For example, if you have a hash, then

(for ([(k v) hash]) ...)
  and
(for ([(k v) (in-hash hash)]) ...)

will always have the same behavior (though not performance). But if you
want to iterate over explicit key/value _pairs_ (i.e., cons cells), then
you'd need to do:

(for ([pair (in-hash-pairs hash)]) ...)

since the default sequence interpretation for a hash is one that produces
two values (the key and value) per-iteration, instead of one that produces
a single cons cell value per-iteration.

Point is, sometimes `in-` is an optimization; in other cases, it
changes the actual way that the data structure is interpreted as a sequence.

- Jon

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


Re: [racket-users] Help with generators from python land!

2019-02-20 Thread Jon Zeppieri
On Wed, Feb 20, 2019 at 5:08 PM Jon Zeppieri  wrote:

>
> (define (reverse-hash h)
>   (for*/fold ([result (hash)])
>  ([(score letters) (in-hash h)]
>   [letter (in-list letters)])
> (hash-set result letter score)))
>
>
As with Jens's answer, we can use `for*/hash` here, as well, and make this
slightly shorter:

(define (reverse-hash h)
  (for*/hash ([(score letters) (in-hash h)]
  [letter (in-list letters)])
(values letter score)))

`for*/hash` is really a specialized version of `for*/fold`, which handles
the hash accumulator for you. The `(values letter score)` expression in the
body indicates how the (implicit) accumulator will be updated.

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


Re: [racket-users] Help with generators from python land!

2019-02-20 Thread Jon Zeppieri
On Wed, Feb 20, 2019 at 4:25 PM Dave McDaniel 
wrote:

> Hello,
>
> I have interest in picking up racket and have done some koans and also
> have been doing the racket track on exercism.
>
> There is a fairly simple exercise called `etl` on exercism related to
> taking a hash for scoring scrabble letters and unpacking it into a flatter,
> more efficient structure for lookups.
>
> The input hash has score as the key and a list of letters of that score as
> the value.  The output is a hash of letter -> score.  One pair per letter
> instead of one pair per score.
>
> It was easy enough to solve with `for-each` using side-effects to update a
> mutable hash, however I think using a generator is a cleaner approach and
> doesn't require mutability.  In python using generators would be very
> straightforward:
>
>
>
Generators are a common tool in Python, but not in Racket. (I've written a
lot of Racket code over many years and have used generators, I think, once.)

I'd do this as a fold over the input hash:

===
#lang racket/base

(define mixed-case-input
  (hash 1 '("a" "E" "I" "o" "U" "L" "N" "r" "s" "T")
2 '("D" "G")
3 '("B" "c" "M" "P")
4 '("f" "h" "V" "W" "y")
5 '("K")
8 '("J" "x")
10 '("q" "z")))

(define (reverse-hash h)
  (for*/fold ([result (hash)])
 ([(score letters) (in-hash h)]
  [letter (in-list letters)])
(hash-set result letter score)))
===

All of the `for*` operations do nested iteration (as opposed to the `for`
operations without the asterisk, where sequences are iterated in parallel).
So, in this case, we get each `(score letters)` pair fro the hash, and for
each of those, we iterate over the list of letters. On each iteration,
we're updating our accumulator (`result`). The result of the whole
expression is the final value of the accumulator.

- Jon

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


Re: [racket-users] [macro help] How can I render a parenthesized set of elements optional?

2019-02-15 Thread Jon Zeppieri
On Fri, Feb 15, 2019 at 11:50 PM David Storrs 
wrote:

>
> #lang racket
> (require (for-syntax racket/syntax syntax/parse))
>
> (define-syntax (struct++ stx)
>   (syntax-parse stx
> [(_ name:id (field:id ...) (~optional (rule:expr ...)) opt ...)
>  #'(begin (struct name (field ...) opt ...)
> (list (~? rule) ... ))]))
>
>
I think this does what you want:
   (list (~? (~@ rule ...)))

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


Re: [racket-users] Multipart HTTP requests

2019-01-30 Thread Jon Zeppieri
On Wed, Jan 30, 2019 at 6:46 AM Christopher Lemmer Webber <
cweb...@dustycloud.org> wrote:

> Jon Zeppieri writes:
>
> > On Tue, Jan 29, 2019 at 4:17 AM Christopher Lemmer Webber <
> > cweb...@dustycloud.org> wrote:
> >
> >>
> >> Any thoughts on how I should move forward?
> >
> >
> > I think that using a `data-procedure/c` of a particular sort should allow
> > you to implement this without needing access to the struct internals or
> > needing to read everything into memory at once.
> >
> > (Though, it would be a bit nicer if the write proc allowed you to specify
> > an offset and length into the string/byte string.)
> >
> > Something like:
> > ===
> > #lang racket/base
> >
> > (require net/http-client
> >  file/sha1
> >  racket/random)
> >
> > (define (http-conn-send/multipart! hc uri multipart-body
> >#:version [version #"1.1"]
> >#:method [method #"POST"]
> >#:close? [close? #f]
> >#:headers [headers '()]
> >#:content-decode [decodes '(gzip)]
> >#:boundary [boundary
> (random-boundary)])
> >   (define content-type-header
> > (string-append
> >  "Content-Type: multipart/form-data; boundary="
> >  boundary))
> >
> >   (http-conn-send! hc uri
> >#:version version
> >#:method method
> >#:close? close?
> >#:headers (cons content-type-header headers)
> >#:content-decode decodes
> >#:data (multipart-body->data-proc boundary
> > multipart-body)))
> >
> > (define (mime-escape s)
> >   (regexp-replace* #rx"[\"\\]" s "\\0"))
> >
> > (define (make-string-part field-name field-value)
> >   (λ (write-chunk boundary)
> > (write-chunk
> >  (format
> >   (string-append "--~a\r\n"
> >  "Content-Disposition: form-data; name=\"~a\"\r\n"
> >   "Content-Type: text/plain; charset=utf-8\r\n"
> >   "\r\n"
> >   "~a\r\n")
> >   boundary
> >   (mime-escape field-name)
> >   field-value
> >
> >
> > (define (make-file-part field-name file-name content-type in)
> >   (λ (write-chunk boundary)
> > (write-chunk
> >  (format
> >   (string-append "--~a\r\n"
> >  "Content-Disposition: form-data; name=\"~a\";
> > filename=\"~a\"\r\n"
> >   "Content-Type: ~a\r\n"
> >   "\r\n")
> >   boundary
> >   (mime-escape field-name)
> >   (mime-escape file-name)
> >   content-type))
> >
> > (define buffer (make-bytes 4096))
> > (let loop ([n (read-bytes-avail! buffer in)])
> >   (cond
> > [(eof-object? n)
> >  n]
> > [else
> >  (write-chunk (subbytes buffer 0 n))
> >  (loop (read-bytes-avail! buffer in))]))
> >
> > (write-chunk "\r\n")))
> >
> > (define (multipart-body->data-proc boundary parts)
> >   (λ (write-chunk)
> > (for ([part parts])
> >   (part write-chunk boundary))
> > (write-chunk (format "--~a--\r\n" boundary
> >
> > (define (random-boundary)
> >   (string-append
> >"--"
> >(bytes->hex-string
> > (crypto-random-bytes 8
>
> Oh, this is useful!  I didn't see this when asking for data-procedure/c
> examples earlier on the list :)
>
> BTW do you mind specifying a license for your code above so I might
> incorporate parts of it into my work?  Maybe either LGPL or Apache v2?
>


Okay, this applies to the code above:

Copyright (c) 2019 Jon Zeppieri

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subjec

Re: [racket-users] Multipart HTTP requests

2019-01-29 Thread Jon Zeppieri
On Tue, Jan 29, 2019 at 4:17 AM Christopher Lemmer Webber <
cweb...@dustycloud.org> wrote:

>
> Any thoughts on how I should move forward?


I think that using a `data-procedure/c` of a particular sort should allow
you to implement this without needing access to the struct internals or
needing to read everything into memory at once.

(Though, it would be a bit nicer if the write proc allowed you to specify
an offset and length into the string/byte string.)

Something like:
===
#lang racket/base

(require net/http-client
 file/sha1
 racket/random)

(define (http-conn-send/multipart! hc uri multipart-body
   #:version [version #"1.1"]
   #:method [method #"POST"]
   #:close? [close? #f]
   #:headers [headers '()]
   #:content-decode [decodes '(gzip)]
   #:boundary [boundary (random-boundary)])
  (define content-type-header
(string-append
 "Content-Type: multipart/form-data; boundary="
 boundary))

  (http-conn-send! hc uri
   #:version version
   #:method method
   #:close? close?
   #:headers (cons content-type-header headers)
   #:content-decode decodes
   #:data (multipart-body->data-proc boundary
multipart-body)))

(define (mime-escape s)
  (regexp-replace* #rx"[\"\\]" s "\\0"))

(define (make-string-part field-name field-value)
  (λ (write-chunk boundary)
(write-chunk
 (format
  (string-append "--~a\r\n"
 "Content-Disposition: form-data; name=\"~a\"\r\n"
  "Content-Type: text/plain; charset=utf-8\r\n"
  "\r\n"
  "~a\r\n")
  boundary
  (mime-escape field-name)
  field-value


(define (make-file-part field-name file-name content-type in)
  (λ (write-chunk boundary)
(write-chunk
 (format
  (string-append "--~a\r\n"
 "Content-Disposition: form-data; name=\"~a\";
filename=\"~a\"\r\n"
  "Content-Type: ~a\r\n"
  "\r\n")
  boundary
  (mime-escape field-name)
  (mime-escape file-name)
  content-type))

(define buffer (make-bytes 4096))
(let loop ([n (read-bytes-avail! buffer in)])
  (cond
[(eof-object? n)
 n]
[else
 (write-chunk (subbytes buffer 0 n))
 (loop (read-bytes-avail! buffer in))]))

(write-chunk "\r\n")))

(define (multipart-body->data-proc boundary parts)
  (λ (write-chunk)
(for ([part parts])
  (part write-chunk boundary))
(write-chunk (format "--~a--\r\n" boundary

(define (random-boundary)
  (string-append
   "--"
   (bytes->hex-string
(crypto-random-bytes 8

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


Re: [racket-users] Are the terms "function" and "procedure" synonymous in Racket?

2019-01-22 Thread Jon Zeppieri
>
> [25 messages]
>

I think Wadler's Law needs an update.

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


Re: [racket-users] Help understanding cond expression

2019-01-12 Thread Jon Zeppieri
On Sun, Jan 13, 2019 at 12:37 AM Hassan Shahin  wrote:

> Thanks Jack and Mike!
>
> You are right. Arguments to procedures will be evaluated before the
> invocation of the procedure.
>

This is true, but it's not really the issue in your case. Even in #lang
lazy, which does not eagerly evaluate procedure arguments, your program
would still be an error, because the expression `John` has no meaning at
all unless you define it. Try the following in both #lang racket and #lang
lazy:

--- definitions window ---
#lang lazy ;; or racket

(define type-of (lambda (item other-message)
  (cond
[(pair? item) 'pair]
[(null? item) 'empty-list]
[(number? item) 'number]
[(symbol? item) 'symbol]
[else
 other-message
 'some-other-type])))

--- interactions window ---
(type-of #\e (displayln "hello"))
(type-of (cons 2 3) (displayln "hello"))
(type-of John (displayln "hello"))

---

The `John` example will fail in both languages, but you'll observe the
difference with the other two examples.

- Jon

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


Re: [racket-users] with-input-from-file question

2018-12-16 Thread Jon Zeppieri
On Sun, Dec 16, 2018 at 2:59 PM Jonathan Simpson  wrote:

> What is the difference between this code, which reads and returns "#lang"
> from the file:
> (define in-file (open-input-file "adventure.rkt"))
> (parameterize ([current-input-port in-file]) (read-string 5))
>
> and this code which appears to still read from stdin:
>
> (with-input-from-file "adventure.rkt" (read-string 5))
>
> I thought with-input-from-file would set the current-input-port to the
> file in basically the same way as the first code segment.
>
> I see this behavior from both DrRacket and Emacs racket-mode.
>
>
`with-input-from-file` takes a thunk (that is, a procedure of 0 parameters)
as its second argument, so your code should be:

(with-input-from-file "adventure.rkt" (λ () (read-string 5)))

I'd expect your code to read from stdin but then raise a contract error
when checking the arguments to `with-input-from-file`.

- Jon

>
>

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


Re: [racket-users] JSON vs. normal Racket for simple serialization to database

2018-12-12 Thread Jon Zeppieri
Postgres can index jsonb column data. Also, other languages will have an
easier time reading it. If neither of those matter for your case, then no.

- Jon


On Wed, Dec 12, 2018 at 10:26 AM Brian Adkins  wrote:

> I have some simple serialization needs. In Ruby, I would always serialize
> an object to JSON and store in a postgres text column. However, w/ Racket,
> it appears another option is to simply use read/write. Any reason not to
> use read/write for serialization instead of JSON?
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] Struct initialization?

2018-03-09 Thread Jon Zeppieri
On Fri, Mar 9, 2018 at 9:35 PM, Kevin Forchione  wrote:

> Is it possible to initialize a struct field based on values from
> previously defined fields? Something equivalent to let* where
>
> >(struct foo (A B C))
> >(foo 1 2) would produce (foo 1 2 3) for example?
>
>
> As far as I know, the only way to do this is to write your own function
that calls the struct constructor. You can do this in a module, and only
export your constructor, instead of the default struct constructor.

If you want the constructor and the match expander to use the same
identifier, then you need to do a bit more work.  For example:

```
#lang racket/base

(require racket/match
 (for-syntax racket/base
 syntax/transformer))

(struct foo* (A B C))

(define (foo a b)
  (foo* a b (+ a b)))

(define-match-expander $foo
  (syntax-rules ()
[(foo a b c) (foo* a b c)])
  (make-variable-like-transformer #'foo))

(provide (rename-out [$foo foo]
 [foo*-A foo-A]
 [foo*-B foo-B]
 [foo*-C foo-C])))
```

Of course, even here, an instance will print as #. You can implement
gen:custom-write to fix that.

There might be a better way to do this, but this is what I've used in the
past.

- Jon

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


Re: [racket-users] struct question

2018-03-07 Thread Jon Zeppieri
On Wed, Mar 7, 2018 at 9:27 PM, Kevin Forchione  wrote:

> Hi guys,
> Can we associate more than 1 generic with a struct? Something like:
>
> (struct foo (..) #:methods gen:bar [] gen:baz [] …)
>
>
>
Yes, except it's:

(struct foo (..) #:methods gen:bar [] #:methods gen:baz [] ...)

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


Re: [racket-users] The Birth and Death of Units

2018-01-22 Thread Jon Zeppieri
There's also Backpack, which adds something similar to ML's module system*
to Haskell, except at the package level:
https://plv.mpi-sws.org/backpack/backpack-paper.pdf

* It's more similar to Rossberg & Dreyer's MixML than it is to Standard ML
or OCaml's module systems.

On Mon, Jan 22, 2018 at 2:13 PM, Matthias Felleisen 
wrote:

>
> I think MLers complain about two things here:
>
> — ML’s module system is basically a language that works at the type level.
> I think OldCamlers mean this mostly.
> — ML’s module system is also a typed lambda calculus whose basic values
> are structs, aka, atomic modules. You can get a sense of this with units.
>
> Haskell lacks both. There is a paper with Harper and Dreyer and a Haskell
> person that tries to connect Haskell with ML at the type level, but not
> comprehensively like the above.
>
> Yes, it is difficult to evaluate an abstraction without having worked with
> them. Not even implementing them helps :-) Let me recommend an exercise:
>
>  work thru the Sendai paper with an SML that finally provides recursive
> functors.
>  https://www2.ccs.neu.edu/racket/pubs/#tacs94-cf
>  (This is the paper that inspired Units. I had coded everything in sml/nj
> when I figured out that you couldn’t tie the knot with functors. So I
> rewrote all of it with Scheme.)
>
> — Matthias
>
>
>
>
>
>
>
> > On Jan 22, 2018, at 1:22 PM, Alexis King  wrote:
> >
> > Thank you for this explanation.
> >
> > I consider myself largely an outsider looking in on module systems, but
> > I often hear SML and OCaml programmers complaining, wondering when
> > Haskell is going to “get a real module system”. I’d like to do right
> > thing in Hackett if I can, but I don’t really know what the right thing
> > is, since I have written precious little ML, and what I have written is
> > certainly not enough to get a feel for how modules affect large program
> > construction. It’s unfortunately difficult (perhaps impossible?) to get
> > an understanding of the usefulness of an abstraction without using it
> > oneself, so maybe I ought to just sit down and write some ML programs.
> >
> > Alexis
> >
> >> On Jan 21, 2018, at 1:26 PM, Matthias Felleisen
> >>  wrote:
> >>
> >> Units were the wrong approach to everyday modularity.They were, and
> >> they are, the correct solution to design problems such as those
> >> explained in our original paper on the idea.
> >>
> >> Units suffer from a large notational overhead for everyday use. The
> >> second edition, due to Owens and Flatt, does a bit better with the
> >> introduction of 'linking inference’ but it was too little too ate. The
> >> other disadvantage of units concerns syntactic abstraction. You really
> >> want to parameterize modules over their implementation language.
> >> Shriram generalized units to unit/lang in his dissertation, but this
> >> proved too difficult to implement. Matthew proposed to make modules
> >> first-order, as opposed to first-class values, and this worked out
> >> well. I still use units on rare occasions, for example to mimic
> >> complex testing contexts and to deploy the same module-level
> >> abstraction _twice_ in the same program. These situations are rare,
> >> however.
> >>
> >> Historical note. ML programmers got it similarly wrong when they
> >> pushed for “fully functorized” style. Once their compilation manager
> >> came online, they abandoned this style too and simply allowed the
> >> linker to connect structs as specified. I happened to be with these
> >> MLers for a year, which inspired me for the unit-like abstraction when
> >> we launched Racket/PLT Scheme. Functors are needed in the same
> >> situations as units but had less expressive power (recursive/dynamic
> >> linking).
> >>
> >> — Matthias
> >
> >
> > --
> > 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+unsubscr...@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: [racket-users] Racket Echo Server/Client hanging

2017-12-05 Thread Jon Zeppieri
On Wed, Dec 6, 2017 at 12:13 AM, Vishal Prasad  wrote:

> And this is the client:
>
>
> (define (hello_socket port)
> (define-values (in out) (tcp-connect "localhost" port))
> (write "hello socket world\n" out)
> (display (read in)))
>
>
> The client does not receive any text back, and just hangs on the read.
>
>
> The `write` is buffered. If you add a `(flush-output out)`, it will work.

- Jon

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


Re: [racket-users] Plumbum for racket

2017-10-24 Thread Jon Zeppieri
Featured at the recent RacketCon:
http://docs.racket-lang.org/rash@rash/index.html

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


Re: [racket-users] Science graphics with Racket?

2017-10-23 Thread Jon Zeppieri
On Mon, Oct 23, 2017 at 3:04 PM, Lawrence Bottorff  wrote:
> I'd like to use Racket to generate scalable (svg?) graphics like gnuplot or
> GeoGebra does. For example, I'd like to create a cartesian coordinate graph
> system, then draw functions on it. One thing in particular would be to draw
> a graph of a circle based on the standard form of a circle, e.g., x^2 + y^2
> = r^2. Again, I'd prefer being able to create an svg file. Is there a
> tutorial that might give me more insight than the reference pages or the
> Quick: An Introduction to Racket with Pictures? Or am I barking up the wrong
> tree?
>
> LB
>

Hi Lawrence,

Have you looked at the plot library? [https://docs.racket-lang.org/plot/]

- Jon

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


Re: [racket-users] How to identify the target of a symlink?

2017-09-28 Thread Jon Zeppieri
https://docs.racket-lang.org/reference/Manipulating_Paths.html?q=resolve-path#%28def._%28%28quote._~23~25kernel%29._resolve-path%29%29

On Thu, Sep 28, 2017 at 5:50 PM, David Storrs  wrote:
> The link-exists? function will tell me that something is a symlink.
> How do I tell what it's pointing to?
>
> I'm writing code that must move data from one computer to another, and
> I need a way to say "create the file here and put the data in it" vs
> "create a symlink here that points to a file over there and put the
> data in the file"
>
> I've been through the Filesystem[1] docs, which offer:
>
> link-exists?   ; Is it a link?
>
> file-or-directory-identity (with as-link? #t) ; get the identity of a
> file, which can prove that a link isn't the same as the file that it
> points to, but doesn't help me find the target
>
> find-executable-file can track through a chain of links so presumably
> there is some way to do it.  Various other functions (e.g. copy-file)
> also can distinguish between links and not-links.
>
>
> A general search of the docs yields a lot of hits to html- and
> collection-related things, but nothing that seems to solve my problem.
>
> [1] https://docs.racket-lang.org/reference/Filesystem.html
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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


Re: [racket-users] "<>&" in script xexprs

2017-09-19 Thread Jon Zeppieri
I haven't tried this, but I think that script source should be in a
cdata structure
[http://docs.racket-lang.org/xml/index.html?q=xexpr#%28def._%28%28lib._xml%2Fmain..rkt%29._cdata%29%29]
to prevent the behavior you're seeing. -J


On Tue, Sep 19, 2017 at 4:36 PM, Byron Davies  wrote:
> In strings, xexpr->xml converts "<>&” into , etc. I’m sure this was 
> well-intentioned, but in my use of web-server, I use javascript scripts 
> through the (script “…”) form.  In loop tests such as “i < n”, Javascript 
> does not grok the transformed text “i  n”.  I tried workarounds for as 
> long as I could (e.g, using the “for key in lst” style of loops), but I 
> reached the end of the line when I wanted to change the contents of a table 
> cell using “cell.innerHTML = ‘’.
>
> But now I have to ask, is there a good way to make this change? In 
> …xml/private/writer.rkt there’s this:
>
> (define escape-table #px"[<>&]”)
>
> Would it make sense to rebind escape-table while inside a (script …) element, 
> or would this screw up something else?
>
> Byron
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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


Re: [racket-users] Re: Do futures actually work? What are they useful for?

2017-09-11 Thread Jon Zeppieri


> On Sep 11, 2017, at 6:39 PM, mrmyers.random.suf...@gmail.com wrote:
> 
> As far as I'm aware, futures usually shouldn't improve performance outside of 
> networking or hardware-latency type situations. The main goal of futures is 
> just time-sharing, not improving performance. It doesn't genuinely do things 
> in parallel, it just interleaves the execution of several things at once.

This isn't true. Futures are for parallelism; they just happen to be defeated 
by many, many operations. More to the point, they're not for interleaving work. 
Racket's threads are for that.

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


Re: [racket-users] Racket Web servlet performance benchmarked and compared

2017-09-10 Thread Jon Zeppieri
On Sat, Sep 9, 2017 at 6:25 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:
> It looks like after roughly 2^14 requests are
> `accept`-ed, there's a *long* delay before the next one succeeds.

Okay, the above happens when the host runs out of ephemeral ports. So,
not a big deal.
---

My tests suggest the same thing (w.r.t. places) that D. Bohdan's do:
that using places consistently lowers the server throughput (even when
there are multiple cores available). Don't know why, though.

I wanted to see if inter-place communication was the bottleneck, so I
made some changes to allow the individual places to do their work
without needing to communicate:

- First, I made tcp-listeners able to be sent over place-channels, so
the only inter-place communication would be at initialization time.

- Then I realized I could accomplish the same goal with a lot less
fuss by changing the meaning of tcp-listen's reuse? parameter so that
it would set SO_REUSEPORT (instead of SO_REUSEADDR) on the listening
socket. (This allows each place to bind to the same port without
needing any inter-place communication at all.)

This did not improve throughput. But it doesn't exactly prove that
inter-place communication isn't a bottleneck, since both of the above
changes required some other changes to rktio, which, for all I know,
may have caused different performance problems. (If multiple OS
threads are polling the same socket, you need to handle the race
between them to accept an incoming connection.)

So, I'm still puzzled by this.

-J

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


Re: [racket-users] Racket Web servlet performance benchmarked and compared

2017-09-09 Thread Jon Zeppieri
On Sat, Sep 9, 2017 at 8:05 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:
> On Sat, Sep 9, 2017 at 7:52 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:
>>
>> It does seem odd, though, that the server seems to *favor* sending
>> ACKs to clients it can't service over responding to the ones it can.
>
> No, there has to be something else wrong. The tcpdump output shows
> significant gaps in time while this ACT/RST game is going on (I'm
> looking at a gap of 8 seconds right now), so there's plenty of time
> where the server is just sitting idle. But, for whatever reason, the
> `poll`-ing Racket program isn't waking up. -J


As it turns out, the same thing happens with the Caddy example, too,
so it seems to be an OS X thing, rather than a Racket thing. -J

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


Re: [racket-users] Racket Web servlet performance benchmarked and compared

2017-09-09 Thread Jon Zeppieri
On Sat, Sep 9, 2017 at 7:52 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:
>
> It does seem odd, though, that the server seems to *favor* sending
> ACKs to clients it can't service over responding to the ones it can.

No, there has to be something else wrong. The tcpdump output shows
significant gaps in time while this ACT/RST game is going on (I'm
looking at a gap of 8 seconds right now), so there's plenty of time
where the server is just sitting idle. But, for whatever reason, the
`poll`-ing Racket program isn't waking up. -J

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


Re: [racket-users] Racket Web servlet performance benchmarked and compared

2017-09-09 Thread Jon Zeppieri
On Sat, Sep 9, 2017 at 6:25 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:
> When I ran experiments similar to yours on OS X I saw some odd
> scheduling behavior. It looks like after roughly 2^14 requests are
> `accept`-ed, there's a *long* delay before the next one succeeds. It
> appears that the program is `poll`-ing, waiting for activity, but, for
> whatever reason, it doesn't receive notice of any for a long time.
>
> - Jon


Okay, it seems this occurs when the listen backlog fills up (the
listen(2) man page on OS X says that the backlog is limited to 128),
at which point the server stops sending SYN-ACKs (it appears to send
ACKs instead), and the clients respond with RSTs. It looks like the
server and client play this game for some time, where the clients
backoff exponentially, so that their reset requests come more
infrequently, until the server can manage to start processing requests
again.

It does seem odd, though, that the server seems to *favor* sending
ACKs to clients it can't service over responding to the ones it can.

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


Re: [racket-users] Racket Web servlet performance benchmarked and compared

2017-09-09 Thread Jon Zeppieri
When I ran experiments similar to yours on OS X I saw some odd
scheduling behavior. It looks like after roughly 2^14 requests are
`accept`-ed, there's a *long* delay before the next one succeeds. It
appears that the program is `poll`-ing, waiting for activity, but, for
whatever reason, it doesn't receive notice of any for a long time.

- Jon

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


Re: [racket-users] Re: Racket Web servlet performance benchmarked and compared

2017-09-07 Thread Jon Zeppieri
On Thu, Sep 7, 2017 at 4:52 PM, dbohdan  wrote:
>
> In both cases the ordering is still "single" > "many" > "places" > 
> "many-places". Though "many" and "places" are pretty close in the first case, 
> "many" consistently comes out ahead if you retest.

This is really interesting. I wonder how costly the inter-place
communication is, relative to the cost of actually generating and
sending the response.

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


Re: [racket-users] Re: Racket Web servlet performance benchmarked and compared

2017-09-04 Thread Jon Zeppieri
On Tue, Sep 5, 2017 at 1:38 AM, dbohdan  wrote:
>
> I've run the default benchmark with the new application, which I've dubbed 
> "racket-custom". (Actually, I had to make a tweak to the benchmark to 
> accommodate the number of requests it was fulfilling. It made ApacheBench 
> overstep its memory quota and get killed.) When started with the "places" or 
> the "many-places" command line argument on Linux, racket-custom quickly runs 
> out of file descriptors. It opens one per request and apparently doesn't 
> close them.

In this code:

  (let loop ()
(define-values (r w) (tcp-accept l))
(place-channel-put jobs-ch-to (cons r w))
(loop)))

after sending the ports to the place and before looping, I think the
ports need to be abandoned:

  (tcp-abandon-port r)
  (tcp-abandon-port w)

- Jon

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


Re: [racket-users] Requiring module beneath top level?

2017-08-18 Thread Jon Zeppieri
On Fri, Aug 18, 2017 at 7:08 PM,   wrote:
>
> Here is an idea of what a plugin registration function could look like:
>
>   (define (load-plugins paths)
> ;; Process one plugin at a time
> (define (load-plugin path)
>   ;; Add the path (or its stem) to the search paths
>   ;; Require the plugin (the plugin should register itself)
>   )
> (vector-map load-plugin paths)
> "Loaded plugins")
>
> The sequence of paths was received from Nvim as a vector, and I map over
> every path, requiring the module/collection. The problem is that I
> cannot use (require (file path)) because the require is not a top- or
> module level. The question is: what can I do instead?

I think you want `dynamic-require`:
[http://docs.racket-lang.org/reference/Module_Names_and_Loading.html?q=dynamic-require#%28def._%28%28quote._~23~25kernel%29._dynamic-require%29%29]

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


Re: [racket-users] Need help with parallelizing a procedure

2017-08-12 Thread Jon Zeppieri
On Sat, Aug 12, 2017 at 6:21 AM, Zelphir Kaltstahl
 wrote:
>
> ~~~
> (define (gini-index subsets label-column-index)
>   (for*/list ([subset (in-list subsets)]
>   [label (in-list (list 0 1))])
> (place pch
>(place-channel-put pch (list subset label label-column-index))
>(let ([data (place-channel-get pch)])
>  (calc-proportion (first data)
>   (second data)
>   (third data))
> ~~~
>
> The `subset` inside `(place-channel-put pch (list subset label 
> label-column-index))` gets underlined and the error is:
>
> subset: identifier used out of context

Two things:

First, regarding the above code, if you look at the docs for `place`,
you'll see: "The `body`s close only over `id` plus the *top-level*
bindings of the enclosing module..." [emphasis added]. You're trying
to treat `subset`, `label`, and `label-column-index` as if they were
in the new place's closure, but those bindings are all local, so
they're not available. In the Rosetta example you cited, `numbers` is
explicitly sent (via a `place-channel-put`) from the main place to the
newly created one. You'd need to do the same.

Second, though, you don't want to do this. Creating a place is
expensive enough that creating several each time you compute a gini
coefficient will probably make your code run very slowly. You mention
that you tried to use a place more than once. That's a better
approach. (Apparently, you had some trouble with that approach, but
yes, it can be done.)

However, you should try using futures instead of places. They're less
expensive to create and generally best suited for numeric tasks like
yours (as the Guide says -- and you should definitely read the section
of the Guide on parallelism
[http://docs.racket-lang.org/guide/parallelism.html].

- Jon

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


Re: [racket-users] Get number of CPUs / Cores

2017-08-08 Thread Jon Zeppieri
On Tue, Aug 8, 2017 at 4:56 PM, Zelphir Kaltstahl
 wrote:
> I want to parallelize some program using places, so actually using multiple 
> cores.
>
> To parallelize as much as possible on any given machine, I'd like to know how 
> many cores + effect of hyperthreading there are.
>
> For example I have a CPU with 2 cores, but it supports hyperthreading, so 
> that I can run 4 processes concurrently. The desired result would then be 4 
> instead of 2.

I think `processor-count` does that:
http://docs.racket-lang.org/reference/futures.html?q=processor-count#%28def._%28%28lib._racket%2Ffuture..rkt%29._processor-count%29%29

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


Re: [racket-users] Re: Decision Tree in Racket - Performance

2017-07-27 Thread Jon Zeppieri
You can get better performance out of the recursive function by using
car/cdr instead of first/rest; first/rest require their arguments to
be lists, whereas car/cdr require theirs to be pairs, which is a lot
cheaper to check. Also, using an optional argument (in a loop,
especially) makes a difference.

Even so, for/sum wins, because it uses ops like unsafe-car and
unsafe-cdr, which it can do safely, since it first establishes that
it's working with a list (and then doesn't have to check again).

- Jon

On Thu, Jul 27, 2017 at 8:55 PM, Daniel Prager
 wrote:
> Revised to collect garbage before each timing shows the recursive function
> isn't too bad (but not great):
>
> cpu time: 405 real time: 404 gc time: 0
> 2452578471
>
> cpu time: 368 real time: 368 gc time: 0
> 2452578471
>
> cpu time: 50 real time: 50 gc time: 0
> 2452578471
>
> cpu time: 194 real time: 195 gc time: 75
> 2452578471
>
>
> Dan
>
> --
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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


Re: [racket-users] Re: Decision Tree in Racket - Performance

2017-07-27 Thread Jon Zeppieri
On Thu, Jul 27, 2017 at 4:01 PM, Zelphir Kaltstahl
 wrote:
> Wow, are those timings for the "big" data set?!
>

Unless I'm mistaken, Daniel's times are for 274 rows of the big data
set, not the whole thing.

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


Re: [racket-users] [ANN] MessagePack implementation for Racke

2017-07-24 Thread Jon Zeppieri
On Mon, Jul 24, 2017 at 4:40 PM, Jay McCarthy  wrote:
> On Mon, Jul 24, 2017 at 3:18 PM, Alejandro Sanchez
>  wrote:
>>> - I'm curious of the performance. In particular, I would expect that a
>>> computed jump in unpack could do you good. Did you try that?
>> I haven’t investigated performance yet. As I said, I am new to Racket, this 
>> is my first time doing anything useful in it, my only previous Scheme 
>> knowledge was from doing the exercises in SICP and dabbling in Guile a bit. 
>> What is a computed jump?
>
> Rather than having a big `cond`, you could look up the function that
> does the work in a vector and then call it. IMHO, msgpack was designed
> with that in mind, because tags that aren't immediate values are all
> nicely ordered. So you'd check the size, subtract a constant, and grab
> the appropriate procedure from a constant vector.
>

Or you can use `case`. Racket's `case` with densely-distributed fixnum
constants (like in your code) will:

1. Use a vector lookup to go from the case label (i.e. the tag value)
to the index of the RHS clause.
2. Use an open-coded binary search on the index to get to the code itself.

(The technique is described here:
http://scheme2006.cs.uchicago.edu/07-clinger.pdf)

You might want to define a macro on top of `case`, though, to handle
ranges of tags, since `case` doesn't have syntax for that.

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


Re: [racket-users] Re: Decision Tree in Racket - Performance

2017-07-24 Thread Jon Zeppieri
Just want to emphasize that the main source of inefficiency in your code is 
what I mentioned in my last message (iterating over the class labels of each 
row instead of the unique class labels of the entire data set). The second 
biggest factor is your structural recursion over a non-recursive data type 
(namely, vectors). Everything else, from a performance perspective, is 
insignificant.

Aside: if I read Daniel's solution correct, he avoids the first issue by 
assuming that it's a binary classification task (that is, that there are only 
two classes).

> On Jul 24, 2017, at 4:08 AM, Zelphir Kaltstahl  
> wrote:
> 
> Wow, thanks for all the feedback, I'll try to get most of the mentioned stuff 
> done and then post an update : )
> 
>> I teach trees and decision trees to freshman students who have never 
>> programmed before, and Racket’s forms of data and functions are extremely 
>> suitable to this domain.
> 
> I think this is relating to using vectors and accessing them by index? How 
> would you represent the data? What forms of data are better suited?
> 
> Mentioned were:
> 
> - struct instead of hash
> - list of vectors instead of vector of vectors
> 
> Your post made me think of functions themselves. Would it be possible to 
> represent the splits as chains of functions and would that have any 
> advantage? Is that what you are hinting at?
> 
> -- 
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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


Re: [racket-users] Decision Tree in Racket - Performance

2017-07-23 Thread Jon Zeppieri
On Sun, Jul 23, 2017 at 10:09 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:
>
> Even after implementing my own suggestions, it's still much slower
> than the python example it was based. Maybe there's an algorithmic
> problem somewhere (aside from the vector iteration I mentioned
> before). At any rate, I'm intrigued now... -J

And... it turned out to be a very small thing indeed. When you iterate
over the class labels, you're supposed to iterate over the set of
*distinct* class labels. In the Python source, this is:

   class_values = list(set(row[-1] for row in dataset))

In your code, you have:

   (let* ([class-labels (data-get-col data label-column-index)] ...)

... where `data-get-col` returns a list the same length as `data`.
And that's where the huge slowdown comes from, since it means many
more iterations in `gini-index`.

-Jon

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


Re: [racket-users] Decision Tree in Racket - Performance

2017-07-23 Thread Jon Zeppieri
On Sun, Jul 23, 2017 at 7:30 PM, Zelphir Kaltstahl
 wrote:
> Hi Racket Users,
>
> The last few days I've been working on implementing decision trees in Racket 
> and I've been following the following guide: 
> http://machinelearningmastery.com/implement-decision-tree-algorithm-scratch-python/
>
> Now I have the following code: https://github.com/ZelphirKaltstahl/racket-ml
>
> I also wrote some tests, I think for every procedure so far.
>
> However, my implementation seems very very slow. It seems each iteration of 
> `iter-features` takes way too much time.
>
> I've tried to stick to the guide and sometimes "outsourced" some procedure.
>
> I started out with using vectors, as I thought I might gain better 
> performance than from lists. In the code I introduced an abstraction layer, 
> which provides things like `data-length`, so that I could in theory change 
> the representation of data and only change those accessors/getters. In the 
> test cases I sometimes did not use the abstraction though.
>
> So far I am not having much side effects in the code and I'd like to avoid 
> them and unsafe operations.
>
> A small `TEST-DATA` set is in the code and another data set I downloaded from 
> the data set repositories. When running with `TEST-DATA` to calculate the 
> best split, it only takes a few milliseconds, while it takes minutes with the 
> other `data-set`.
>
> How can I make my code more efficient, without changing the basic logic of it?
> Should I not use vectors (what else?)?
> Would I gain anything from using typed Racket or flonums?
>


Even after implementing my own suggestions, it's still much slower
than the python example it was based. Maybe there's an algorithmic
problem somewhere (aside from the vector iteration I mentioned
before). At any rate, I'm intrigued now... -J

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


Re: [racket-users] Decision Tree in Racket - Performance

2017-07-23 Thread Jon Zeppieri
On Sun, Jul 23, 2017 at 9:07 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:

> Struct update does, however, involve a full copy[...]

Err, immutable struct update, that is (in case it wasn't obvious).

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


Re: [racket-users] Decision Tree in Racket - Performance

2017-07-23 Thread Jon Zeppieri
On Sun, Jul 23, 2017 at 7:30 PM, Zelphir Kaltstahl
 wrote:
>
> How can I make my code more efficient, without changing the basic logic of it?
>

In addition to what I wrote before, there are a couple of places where
you're constructing new lists when you don't need to. In `gini-index`,
for example, you don't actually need the intermediate lists that
you're summing over. You can instead use `for*/sum` and make the whole
thing a lot simpler and more efficient:

(define (gini-index subsets class-labels label-column-index)
  (for*/sum ([subset (in-list subsets)]
 [class-label (in-list class-labels)])
(calc-proportion subset class-label label-column-index)))

(This is under the assumption that you've changed your data
representation to a list, which you really should.)

And you can make a similar simplification to `calc-proportion`.

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


  1   2   3   >