soegaard2
2019-7-3 11:46:24

@sydney.lambda Nice idea. If you are interested in an example of how to implement basic types, you can look at types.rkt and compiler.rkt from MiniPascal. The compiler is on purpose simple and has a lot of comments.



synth
2019-7-3 11:49:04

@synth has joined the channel


sydney.lambda
2019-7-3 13:19:57

@samdphillips Thanks, the 2nd edition is the one I own so that’s good to know. The later editions seems to be a bit meatier in those sections, but there’s plenty for me to be getting on with in the 2nd edition for sure. I think what I was considering last night could be considered an interpreter that computes types: having a tenv argument that gets passed along which records the type of each bound name; “apply” would then compare the types of the evaluated arguments with the types of the expected/declared arguments, and the type of the evaluated function with the expected/declared return type. @soegaard2 Seems to be just what I was looking for, thank you :slightly_smiling_face: I’ll be having a good read tonight to see how much I can grok.


soegaard2
2019-7-3 13:31:54

@sydney.lambda Don’t hesitate to ask if something looks odd.


sydney.lambda
2019-7-3 13:35:38

@soegaard2 Thanks :slightly_smiling_face:


sydney.lambda
2019-7-3 13:53:45

@soegaard2 apologies in advance for my lack of syntax-parse knowledge. In this piece of code: (define (compile-simple-type stx) ; simple-type : type-identifier \| index-range (syntax-parse stx [(_ (~and sub ((~datum type-identifier) . _))) (compile-type-identifier #'sub)] could you give a layman’s explanation of what’s happening here? I’m struggling to imagine what an actual “concrete” piece of syntax that would be matched by this case would look like.


sydney.lambda
2019-7-3 13:54:34

sub is being bound to something in the event that the piece of syntax encountered is a type-identifier? Then it gets compiled.


lexi.lambda
2019-7-3 13:57:37

A concrete piece of syntax that might match would be (compile-simple-type (type-identifier 42)), and sub would be bound to (type-identifier 42).


sydney.lambda
2019-7-3 14:00:35

ah, so ~datum is just literally “type-identifier” or whatever text comes after ~datum. Thank you, I thought it was ensuring something was a type-identifier, or something like that.


lexi.lambda
2019-7-3 14:02:04

Yes, (~datum x) matches x as a literal datum, in the same way as if x was provided to #:datum-literals.


sydney.lambda
2019-7-3 14:02:40

Thanks :slightly_smiling_face:


sydney.lambda
2019-7-3 14:09:23

Just out of curiosity (this is all very new to me) if you used: #:datum-literals type-identifier, would it end up being: [(_ (~and sub (type-identifier . _))) ... instead?


lexi.lambda
2019-7-3 14:28:53

Yes, that’s right (though it would technically be #:datum-literals [type-identifier]).


sydney.lambda
2019-7-3 14:30:42

I see, thank you very much.


sydney.lambda
2019-7-3 17:21:20

If I have a list of keys like so: '(x y z) and a list of values like so: '(1 2 3) what’s the best way to create a hash table out of them that maps x to 1, y to 2, z to 3 and so on?


sydney.lambda
2019-7-3 17:22:51

I’m currently using: (let iter ([vars vars] [vals vals] [env env]) (if (null? vars) env (iter (cdr vars) (cdr vals) (hash-set env (car vars) (car vals))))) but I figure I’m missing one in the stdlib.


lexi.lambda
2019-7-3 17:23:02

(make-hash (map cons ks vs)) or (for/hash ([k (in-list ks)] [v (in-list vs)]) (values k v))


lexi.lambda
2019-7-3 17:23:52

IIRC the first is actually faster in microbenchmarks, anyway (though I suppose it might allocate more), so you probably might as well use the shorter version


sydney.lambda
2019-7-3 17:24:16

Thank you :slightly_smiling_face:


sydney.lambda
2019-7-3 17:25:02

I’d then have to combine it with the already-existing hash, right?


sydney.lambda
2019-7-3 17:26:30

hash-union seems to work okay. edit: sorry, I didn’t even mention I wanted to add the new bindings to a preexisting hash.


lexi.lambda
2019-7-3 17:27:52

yeah, hash-union would be the easiest (and probably best) way


samdphillips
2019-7-3 17:28:02

something like this would work as well (for/fold ([h old-hash]) ([k k*] [v v*]) (hash-set h k v))


samdphillips
2019-7-3 17:28:14

(hastily typed)


lexi.lambda
2019-7-3 17:29:37

yeah, that would do it directly. it may or may not be more efficient, for some notion of efficient.


sydney.lambda
2019-7-3 17:29:44

yes, that’s much better than the named let; I need use for/fold more.


sydney.lambda
2019-7-3 17:29:54

Thank you both :slightly_smiling_face:


lexi.lambda
2019-7-3 17:30:30

for/hash is just that for/fold with an empty initial hash