laurent.orseau
2020-3-17 08:00:20

Here’s an email from 1987 about pattern matching in Scheme84: https://groups.csail.mit.edu/mac/ftpdir/scheme-mail/HTML/rrrs-1987/msg00090.html This suggests that PLT Scheme had at least some simple pattern matching very early on.


samth
2020-3-17 10:47:07

Matthias wrote a pattern matcher in the 80s that Racket’s match descends from in some sense


samth
2020-3-17 10:47:36

Although it’s been rewritten from scratch at least 3 times


popa.bogdanp
2020-3-17 11:04:51

I tend to write the JSON-generating functions manually and reference the fields using the accessors that deta generates. If you want to generate entry->json style functions, then you can look up the struct info to generate functions at compile time.


popa.bogdanp
2020-3-17 11:05:19

Here’s one way to do it using Alexis King’s syntax-classes library:

https://gist.github.com/Bogdanp/856b98edb6d4525787f30253132cf565

This works for all structs (including deta schemas), but doesn’t support inheritance.


popa.bogdanp
2020-3-17 11:07:54

It’s also possible to do this at runtime by inspecting the field metadata from deta, but that functionality is currently private (see deta/private/field.rkt and deta/private/meta.rkt if you’re interested).


ecb10
2020-3-17 13:22:53

this will be because I turn the input to the parser into a list of characters before processing…


ecb10
2020-3-17 13:23:16

I did originally use a String, then take the tail of the string a lot, which was doing loads of allocation and was therefore really slow (in Chez, at least)


samth
2020-3-17 13:25:10

yes that will be very bad


ecb10
2020-3-17 13:25:22

I’m just generating the chez


samth
2020-3-17 13:25:42

thanks


ecb10
2020-3-17 13:25:49

Idris 1 just moves the pointer along for tail since it won’t get overwritten


samth
2020-3-17 13:26:09

trying to modify the racket code to work in chez would take longer


samth
2020-3-17 13:26:17

is there a reason not to do that in the scheme code?



ecb10
2020-3-17 13:28:15

I didn’t find a way to do that in scheme. Is there something I’m missing?


samth
2020-3-17 13:28:43

i guess i’m confused — can’t you just use an integer?


ecb10
2020-3-17 13:29:43

Hmm, I suppose if strings were represented as a pair of the string and offset (which is what Idris 1 does) it might work


samth
2020-3-17 13:39:23

that chez code doesn’t seem to actually do the parsing


samth
2020-3-17 13:39:51

as in, it takes no time to run


samth
2020-3-17 13:44:31

ah, I have to run it with --script


samth
2020-3-17 13:46:20

for me, if I wrap the unsafePerformIO call in time, the fastest I can get racketcs (using unsafe vector access) is 346 ms. for plain chez using the code you just sent, it’s 271 ms.


ecb10
2020-3-17 13:48:27

I switched to unsafe vector access and I now get 0.731s for racketcs, 0.287 for chez


samth
2020-3-17 13:48:35

using optimize-level 3 at the command line for chez gives me 248 ms


ecb10
2020-3-17 13:49:04

right, that’s where my number is coming from (Idris also generates a .so that way)


samth
2020-3-17 13:49:33

I think the difference between 346 and 731 is code loading time for Racket


ecb10
2020-3-17 13:50:06

if it’s startup cost that’d be understandable


samth
2020-3-17 13:50:30

including loading libraries, particularly the r6rs ones in this case


samth
2020-3-17 13:50:53

if you time things with a use of the time form (works in Racket and Chez) then you’ll see the difference


soegaard2
2020-3-17 13:52:54

@pmatos @pocmatos Thanks for the racket-cas shout out in the new Racket News.


samth
2020-3-17 13:52:58

but I still don’t understand the last 100ms of difference


anything
2020-3-17 15:05:41

The procedure to translate structures to jsexpr seems to assume every value in the structure is a legal JSON value. So, here’s what happens when we use datetime objects.

racket@db.rkt> (offering->jsexpr of1) '#hasheq((ng-date-end . #<datetime 2021-03-25T00:00:00>) (ng-date-reg-end . #<datetime 2020-05-09T23:59:00>) (ng-date-reg-start . #<datetime 2016-10-07T00:00:00>) (ng-date-start . #<datetime 2016-10-07T00:00:00>) (ng-days . "Monday") (ng-description . "") (ng-id . 3798) (ng-item-id . "SES70364") (ng-locations . "Mount Airy") (ng-name . "Swim Inc.") (ng-program-id . "TMP1376") (ng-program-name . "Aqua Exercise") (ng-state . "open") (ng-time-end . "13:00") (ng-time-start . "12:00"))

The hash table is created fine, but since it contains illegal JSON values, jsexpr->string can’t do its job.

racket@db.rkt> (require json) racket@db.rkt> (jsexpr->string (offering->jsexpr of1)) jsexpr->string: expected argument of type <legal JSON value>; given: #<datetime 2020-05-09T23:59:00> racket@db.rkt>

As another minor problem, the struct fields seem to have this ng- prefix.

Here’s how I’m considering solving this difficulty. By asking the database for the table columns…

(define (offerings-fields) (define headers (rows-result-headers (query db-conn "select * from offerings limit 0"))) (for/list ([h headers]) ; the cdr of the car of the header (string->symbol (cdar h))))

…I can get a list of all field names. These names were given by deta from the schema definition. I should be able to just zip these names with the deta’s structure.

racket@db.rkt> (cdr (struct->list of1)) '(3798 "SES70364" "Swim Inc." "" "open" "Mount Airy" #<datetime 2016-10-07T00:00:00> #<datetime 2021-03-25T00:00:00> #<datetime 2016-10-07T00:00:00> #<datetime 2020-05-09T23:59:00> "12:00" "13:00" "Monday" "Aqua Exercise" "TMP1376") racket@db.rkt>

I don’t know how to create an immutable hash table from these values because hasheq requires me to list all values out in a single call to hasheq. But I can manage to using a mutable hash table. I’m going to try that approach. Thanks so much for your assistance!


anything
2020-3-17 15:09:00

If I have a list of values (field1 field2 ... fieldN) and a list of values (val1 val2 ... valN), how could I create a hasheq out of them? The constructor seems to require me to write (hasheq field1 val1 field2 val2 ... fieldN valN) and I don’t know how to do that from these two lists. I feel I need some kind of hasheq-apply.


soegaard2
2020-3-17 15:10:56

You can use make-hash like this (make-hash (map cons elements values)).


samth
2020-3-17 15:11:15

@anything (make-immutable-hasheq (map cons keys vals))


anything
2020-3-17 15:15:54

Wonderful! Thanks!

racket@db.rkt> (make-immutable-hash (map cons (offerings-fields) (cdr (struct->list of1)))) '#hash((date_end . #<datetime 2021-03-25T00:00:00>) (date_reg_end . #<datetime 2020-05-09T23:59:00>) (date_reg_start . #<datetime 2016-10-07T00:00:00>) (date_start . #<datetime 2016-10-07T00:00:00>) (days . "Monday") (description . "") (id . 3798) (item_id . "SES70364") (locations . "Mount Airy") (name . "Swim Inc.") (program_id . "TMP1376") (program_name . "Aqua Exercise") (state . "open") (time_end . "13:00") (time_start . "12:00"))

I thought I should see hasheq and not hash. In my mind hash is a mutable hash and hasheq is an immutable hash. But I guess that’s not so?


samth
2020-3-17 15:30:21

hash vs hasheq is about the equality used for the keys


samth
2020-3-17 15:30:43

make-hash and make-hasheq both construct mutable hashes


samth
2020-3-17 15:31:01

hash and hasheq construct immutable hashes


anything
2020-3-17 15:32:57

Oh, I totally misunderstood. Thanks for clarifying that.


samth
2020-3-17 15:33:25

make-immutable-hasheq of course constructs immutable ones


rokitna
2020-3-17 19:46:11

You can also build one up using hash-set, or you can build up an association list and pass it to make-immutable-hasheq.


samth
2020-3-18 01:33:50

I asked Matthew to take a look at your code, here’s the summary he gave: > To summarize: slower in Racket CS because the code size makes Racket fall back to an interpreted shell with individually compiled small functions at the leaves (in this case, a very bushy tree), and looks even slower when running from compiled files, because the individual functions have to be deserialized (on demand, so in the timed path).


samth
2020-3-18 01:34:47

if you run it env PLT_CS_COMPILE_LIMIT=10000000 it should perform the same as in Chez


samth
2020-3-18 01:35:16

there’s not a non-environment variable way to access that setting, if you end up needing it we could talk about it.


samth
2020-3-18 01:35:42

but also, if you run the parser twice, the second time should be much closer to the chez performance


samth
2020-3-18 01:37:30

Well, I just tested and it’s only a little better


xuuexu
2020-3-18 05:39:39

hi, is there any func can help me to unwrap a list (unwrap-list '((1) (2))) => '(1) (2)


sorawee
2020-3-18 05:40:05

'(1) (2) is not a Racket value


xuuexu
2020-3-18 05:40:43

oh.. it should be '(1) '(2)


michaelmmacleod
2020-3-18 05:45:11

Does (apply values '((1) (2))) work for your use case?


sorawee
2020-3-18 05:46:21

that’s not a Racket value either. But they are Racket multiple values.


xuuexu
2020-3-18 05:47:54

yes, it’s great