
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.

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

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

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.

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.

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).

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

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)

yes that will be very bad

I’m just generating the chez

thanks

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

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

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


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

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

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

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

as in, it takes no time to run

ah, I have to run it with --script

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.

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

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

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

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

if it’s startup cost that’d be understandable

including loading libraries, particularly the r6rs ones in this case

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

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

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

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!

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.

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

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

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?

hash vs hasheq is about the equality used for the keys

make-hash and make-hasheq both construct mutable hashes

hash and hasheq construct immutable hashes

Oh, I totally misunderstood. Thanks for clarifying that.

make-immutable-hasheq of course constructs immutable ones

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

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).

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

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

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

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

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

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

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

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

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

yes, it’s great