@samth Thanks. I guess I’ll give up on that for now. Maybe eventually I’ll dig for the long answer.
The longer answer is that (current-input-port)
in DrRacket is that box
the DrRacket Interactions window isn’t a terminal that you can just type into
you could implement something like that instead of the interactions window but that would be different, not just a mode
@samuel.falcon.fdez has joined the channel
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!
@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.
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
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.
You could also use structs with mutable fields or other imperative functionality directly.
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)
@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