bkovitz
2018-10-22 15:46:24

@samth Thanks. I guess I’ll give up on that for now. Maybe eventually I’ll dig for the long answer.


samth
2018-10-22 15:46:59

The longer answer is that (current-input-port) in DrRacket is that box


samth
2018-10-22 15:47:31

the DrRacket Interactions window isn’t a terminal that you can just type into


samth
2018-10-22 15:47:55

you could implement something like that instead of the interactions window but that would be different, not just a mode


samuel.falcon.fdez
2018-10-22 18:32:00

@samuel.falcon.fdez has joined the channel


cawright.99
2018-10-23 01:37:08

I’m trying to write a simple network (s1 <-> s2): #lang racket (struct node (arc)) (struct arc (trigger destination)) (define s1 (node ([arc 'some-trigger s2]))) (define s2 (node ([arc 'some-other-trigger s1]))) (define (get-destination node) (let ([arc (node-arc node)] [destination (arc-destination arc)]) destination)) (get-destination 's1) but I get s2: undefined; cannot reference an identifier before its definition

I think I understand that after reading a little about top-level. What is the most sensible way to deal with this?

This works, but … ugly!

#lang racket
(struct node (name arc))
(struct arc (trigger destination))

(define M (make-hash))

(define s1 (node "s1" (arc 'some-trigger "s2")))
(define s2 (node "s2" (arc 'some-other-trigger "s1")))

(hash-set! M "s1" s1)
(hash-set! M "s2" s2)


(define (get-destination node)
  (let* ([arc (node-arc node)]
         [destination (hash-ref M (arc-destination arc))])
    destination))

(node-name (get-destination (get-destination s1)))

thanks for any suggestions!


philip.mcgrath
2018-10-23 04:08:30

@cawright.99 This isn’t specific to the “top-level” per se (and your code is in a module, not at the top level). Your s1 and s2 are cyclic, graph-structured data. There are various ways to construct cyclic data, but they basically boil down to using mutation or built-in features of the Racket run-time system.


philip.mcgrath
2018-10-23 04:09:32

For build-in features, the most elegant way is probably shared: http://docs.racket-lang.org/reference/shared.html You can also use make-reader-graph and the placeholder system: http://docs.racket-lang.org/reference/pairs.html?q=make-reader-graph#%28def._%28%28quote._~23~25kernel%29._make-reader-graph%29%29


philip.mcgrath
2018-10-23 04:11:12

I would personally tend to use lazyness in the form of promises: http://docs.racket-lang.org/reference/Delayed_Evaluation.html These are really implemented in terms of mutation, but they encapsulate the imperative parts well away from the rest of your code.


philip.mcgrath
2018-10-23 04:12:08

You could also use structs with mutable fields or other imperative functionality directly.


philip.mcgrath
2018-10-23 04:16:31

Here’s an example with promises: #lang racket (struct node (arc) #:transparent) (struct arc (trigger destination) #:transparent) (define s1 (node (arc 'some-trigger (delay s2)))) (define s2 (node (arc 'some-other-trigger (delay s1)))) (define (get-destination node) (let* ([arc (node-arc node)] [destination (arc-destination arc)]) (force destination))) (get-destination s1)


cawright.99
2018-10-23 04:30:30

@philip.mcgrath - yep, not top-level - I hadn’t seen the difference b/n a module and top level! And thanks for the references - I’ll go off and learn some stuff. :slightly_smiling_face:. I appreciate the example, too