matrix

Benjamin C 2022-12-16T21:26:26.383979Z

@hiskennyness I think I must be missing something... I'm getting a :c-reset-rejecting-undeferred! even after wrapping it with with-integrity ... I'll see if I can reproduce in a simplified example.

kennytilton 2022-12-16T22:45:17.860549Z

OK, ready when you are. If you just want to send along a wodge of code, that is fine, too.

Benjamin C 2022-12-16T22:48:45.880929Z

I cheated and used an atom for the sake of not getting stuck.. and now I'm stuck on a new problem. "Wodge" in thread:

Benjamin C 2022-12-21T08:21:18.624679Z

Ah yes, "what (we seek)" is indeed what I had in mind.

Benjamin C 2022-12-21T08:22:01.694419Z

Maybe you already demo-ed that in your write-up, let me take another look...

Benjamin C 2022-12-21T08:23:39.012609Z

Aha! > fm-ancestor parent chain search > Usage: : (fm-ancestor _what_ _where_) Example: (fget (fm-ancestor :my-radio-group me) :current-choice) Parameters: what : a test function indicating if a model is the one sought; where : the starting model of ancestor search; options : me? : [false] should the starting where model be tested for a match? wocd? : [true] should dependencies /not/ be formed when cell properties are read? Short for "without-cell-dependency". must? : [true] should an exception be thrown if search fails? ie, "Must the navigation find the target what? > In brief, search recursively up testing parents for a match.

kennytilton 2022-12-21T09:23:59.996899Z

I think I got distracted in the middle of that and never got to fm-navig, the one for which I got the Apple Pen so I could draw depth-first, left-right. 🙂 I can offer a quick tl;dr on that if needed--I will be heads down coding for a couple of days, otherwise.

kennytilton 2022-12-21T12:55:42.016119Z

tl;dr: A full search • starts with me, then • kids recursively, depth first, left to right, then • parent recursively, skipping me. Note: if we say :inside? false, we do not search the kids of the starting 'wher', but when we head up to the parent the resursive call always says :inside? true. ie, :inside false is just for the original "where".

👍🏻 1
Benjamin C 2022-12-19T23:53:43.840089Z

It flies indeed! 🚀 Thanks! Ah okay haha, yeah I was a bit confused by that. Thought maybe it meant because it's not guaranteed to succeed and run or something.

kennytilton 2022-12-18T09:08:53.461259Z

Hmm, that :async? true combined with await has my attention. Lemme check sth....

kennytilton 2022-12-18T09:34:57.118579Z

[By the time I got to the end of this I decided a good quick experiment would be to simply remove the :async? true. Then what happens? -kt] Below is the handling of :async? true. Tl;dr: it expects a Future as the computed value. Once `connected? is true, we return --- well, is it a vector of services or a Future? Perhaps we could capture the return value in a local var, print it, then return it. Looking at the MX handling it should throw an exception if it does not get a future (or nil). await is tricky. If it is working as we would like, then your formula will not return a Future. Sadly, await never works the way I expect. :)

(do
                       (assert (or (nil? raw-value)         ;; someday support other default future cell values, mebbe :pending
                                 (dart/is? raw-value Future))
                         (str "cnset-future got non future: " raw-value dbgid dbgdata))

                       (if (dart/is? raw-value Future)
                         (do
                           ;; (dp :got-future :defchg cty/*defer-changes* :wii cty/*within-integrity*)
                           (.then ^Future raw-value
                             (fn [fu-val]
                               ;(dp :then-callback-sees :defchg cty/*defer-changes* :wii cty/*within-integrity*)
                               (with-integrity [:change :future-then]
                                 ;; todo if a cfu is meant to run repeatedly as dependencies change,
                                 ;;      do we need to clear :then? Or is opti-away not a problem
                                 ;;      since it would have happened were there no users??
                                 (rmap-meta-setf [:then? c] true)
                                 (c-value-assume c (if-let [and-then (:and-then? @c)]
                                                     (and-then c fu-val) fu-val) nil))))
                           ;; forcing nil pending future
                           ;; TODO support :pending-future-placeholder-value and force that instead
                           (c-value-assume c nil propagation-code))
                         (c-value-assume c nil propagation-code)))
I would note that :async? true is kind of a gratuitous nicety trying to be helpful, but we can easily handle async ourselves by (1) creating a second cI cell and then (2) having the watch handle the Future. Might help to bypass the nicety since it might be obscuring the action. So: • just have the formula do (.discoverServices device) • confirm we see a Future as new-value in the watch • emulate the async? handling with a .then that assigns the devices to a second cell But, hey, if await is working, just take off the :async? true.

kennytilton 2022-12-18T09:44:27.851679Z

That last sequence improved and as code (but check it! I just banged it in):

:services-lookup (cF+ [:watch (fn [_ _ lookup-future _ _]
                                    (when lookup-future
                                          (.then lookup-future
                                                (fn [results]
                                                      (with-cc :svs-lookup
                                                           (mset! me :services 
                                                               (mapv (fn [service]
                                                                              (md/make
                                                                                    :service service
                                                                                    :characteristics (.-characteristics service)))
                                                                  results)))))]
                         (when (mget me :connected?)
                             (.discoverServices device))
   :services (cI nil)

kennytilton 2022-12-18T12:59:58.359179Z

Hmm, howseabout I extend things so we have instead of :async? and :async parameter, which can be true for the current behavior or a map with two optional keys:

:until _pending_value_, default nil
    :then _result_handler_, defaulit `identity
` We need until, I think, to differentiate the pending state from a null result. Lemme see if I can knock this off before the game. btw, I dug out my prior phone, an LG Android. My Mac allows it to connect then opens an Android file transfer tool. Maybe that is why flutter run does not find my phone? Any ideas?

kennytilton 2022-12-18T13:12:05.432309Z

Wow, I must be overloaded, forgot I supported this (from the TodoMVC demo):

(cF+ [:async? true
                         ; optional chance to filter async response before it
                         ; gets set as the mx slot value
                         :and-then? (fn [c lookup]
                                      (= 200 (.-statusCode ^dht/Response lookup)))]
                     (dht/get (.https Uri "" "drug/event.json"
                                {"limit"  "1"
                                 "search" (str "patient.drug.openfda.brand_name:"
                                            (mget me :title))})))

kennytilton 2022-12-18T13:23:45.772529Z

Untested (but the Todo version works):

:services  (cF+ [:async? true
                 :and-then? (fn [c services]
                             (mapv (fn extract-services
                                     [^ble/BluetoothService service]
                                     (dc/print [:got-svc (.-characteristics service)])
                                     (md/make
                                       :service service
                                       :characteristics (.-characteristics service)))
                               services))
                 :watch obs-slot-new]
             (when (mget me :connected?)
               (.discoverServices device)))
Let me know if that flies, @zenflowapp

Benjamin C 2022-12-20T22:22:24.766179Z

Hrm, so this is interesting. (.discoverServices device) gets called when expected on connection. :and-then? ... runs not when the future resolves, but after :connected? is set back to false.

Benjamin C 2022-12-20T22:24:01.044079Z

Didn't notice at first because it disconnected quickly enough that it happened in close proximity in original testing. @hiskennyness

Benjamin C 2022-12-20T22:34:22.513459Z

Trying manual version without and-then? above...

Benjamin C 2022-12-20T22:39:34.248949Z

Oh wait, maybe the future isn't finishing when I expect...

Benjamin C 2022-12-20T23:07:47.786239Z

Oh, wait, maybe (.discoverServices device) is a future that returns yet another future??

Benjamin C 2022-12-20T23:09:56.046719Z

Nope.

Benjamin C 2022-12-20T23:22:05.390619Z

Hmm, this is not what I expected. :got-services!!!!!!!!! prints right when expected. Future does indeed return. :running-the-with-cc!!!!! on the other-hand, does not run until connection is closed. I suspect now would be a very good time to upgrade the f/mx sha to the latest and see if it is mx isolation related.

Benjamin C 2022-12-20T23:40:07.074359Z

Aha, need with-mx-isolation around with-cc in the and-then? and now it works!

Benjamin C 2022-12-20T23:41:32.777519Z

(Or at least, that's how I got it working in my and then substitute above.)

Benjamin C 2022-12-20T23:53:10.597649Z

@hiskennyness wrapping this here with with-mx-isolation ought to do the trick: https://github.com/kennytilton/flutter-mx/blob/9a23237807af77ba09d397114b7bc2aec7655ae7/src/tiltontec/cell/evaluate.cljd#L205 only I don't know if that might break something else...

Benjamin C 2022-12-21T00:00:14.584869Z

Should be okay right? Cause .then is a top-level event?

kennytilton 2022-12-21T00:06:28.457389Z

Good point. Did you run into something, or are you just thinking ahead?

kennytilton 2022-12-21T00:12:21.790919Z

I will give it a try....

Benjamin C 2022-12-21T00:13:42.606549Z

Yep, this problem here was caused by it: https://clojurians.slack.com/archives/CKCBP3QF9/p1671574944766179?thread_ts=1671230925.880929&cid=CKCBP3QF9

kennytilton 2022-12-21T00:20:27.403409Z

Uh-oh. I worried a bit about that, but mebbe not enough. Do you have a larger chunk of code to remind me of the context, or has this been pushed to "huh"?

Benjamin C 2022-12-21T00:21:49.684089Z

Has been pushed, yes. What is currently there works by side-stepping and-then?

kennytilton 2022-12-21T00:23:08.488629Z

brb...

kennytilton 2022-12-21T00:32:02.753649Z

Hmm. When connected? goes to false the services formula should return nil and no Future should get dispatched, and any and-then should not run. How does connected? get set to false?

Benjamin C 2022-12-21T00:34:15.619109Z

Correct, but the future already had been dispatched from when it was first connected.

kennytilton 2022-12-21T00:34:25.329309Z

I find myself wondering if a Future can fire a second time kind of on its own. Do you see this fire after connected? goes to false?

(dc/print :!connected--discovering-services)

Benjamin C 2022-12-21T00:36:08.385569Z

Nope.

Benjamin C 2022-12-21T00:36:48.483089Z

I think it was simply an interference due to the lack of with-mx-isolation around the with-integrety

kennytilton 2022-12-21T00:40:50.430029Z

Let me push the new version with a with-mx-iso around that. Tests out OK.

👍🏻 1
Benjamin C 2022-12-21T00:41:01.585629Z

IE. the reason I did not see the results of and-then was because

(with-integrity [:change :future-then]
                                 ;; todo if a cfu is meant to run repeatedly as dependencies change,
                                 ;;      do we need to clear :then? Or is opti-away not a problem
                                 ;;      since it would have happened were there no users??
                                 (rmap-meta-setf [:then? c] true)
                                 (c-value-assume c (if-let [and-then (:and-then? @c)]
                                                     (and-then c fu-val) fu-val) nil))))
is waiting for the current change to propagate, but because of the polluted dynamic vars, it doesn't happen until the next time those are externally manipulated.

kennytilton 2022-12-21T00:43:07.578739Z

SHA 28420793ebf4d2639da3c8ccd622e379c8729039

kennytilton 2022-12-21T00:45:48.016139Z

I am a bit groggy, but I think your analysis is spot on. That and-then handling is just mset! in-lined, and we have learned we need with-mx-isolation in CLJD+Flutter around seemingly top-level mset!s

Benjamin C 2022-12-21T01:55:02.506619Z

👍🏻 New sha works beautifully :)

Benjamin C 2022-12-21T02:44:24.737749Z

Looking forward to an example of matrix navigation with a qualification function now that I'm done (for now 🤞🏻) distracting you with other things! :)

kennytilton 2022-12-21T07:47:04.920949Z

Hey, thanks for pushing f/mx and diagnosing the breakage! The idea of dynamic vars being visible in callbacks from Dart/Flutter has me scratching my head as to whether its a bug or a feature. 🙂 A dynamic binding is sth we find in the operative call stack. Our callbacks from Dart/Flutter are seeing bindings extant when the first-class function callback is created, not in the call stack. In Common Lisp, If we want to capture dynamics, we have to convert them to locals and close over them:

(let [my-dyno *some-dyno*] ...return first-class function that references my-dyno...)
I think. 🙂 Anyway thanks again!

kennytilton 2022-12-21T07:48:02.062179Z

"an example of matrix navigation with a qualification function" Qualification function?

kennytilton 2022-12-21T07:56:20.204139Z

If by qualification function you mean that the "what (we seek)" parameter can be a function, that is just a general principle of making a low-level utility as flexible as possible. In CL, all the list comprehension utilities take optional parameters :key :and :test, and :from-end as well. The defaults there being, in CLJ-ese, identity, =, and false. I leave the options to macrology that supplies a test, except no from-end is possbible.

kennytilton 2022-12-17T08:41:47.335059Z

Looks like I should start from pbvm-admin.blue? @zenflowapp

kennytilton 2022-12-17T09:34:23.256849Z

I am crashing back into bed. I saw this nifty stuff:

(await (.delayed dc/Future (dc/Duration .milliseconds 2000)))
Looks like you know your way around Dart futures. Can I replace the whole connect! with code in gen-device-mx that async waits 100ms and then does (mset! device-mx :status :ble-connected)? Then the connected? formula looks for plain keyword :ble-connected. I am looking at this code in gen-device-mx:
(.listen (.-state device)
              (fn [state]
                (mset! device-mx :status state)))
If I could kick off a fake delayed connection right there it seems like that would give us the async we need. 🛏️ 🙂

kennytilton 2022-12-17T12:18:11.064169Z

Hmm, I should try running the thing for real. Still shooting for noon.

kennytilton 2022-12-17T12:29:51.976559Z

Hey, she came up fine, just not finding the connections. More in a few hours, got tennis and brunch next.

kennytilton 2022-12-17T19:43:24.120249Z

A bit puzzled. Before I get into anything, on the "huh" branch pbvm-admin.core starts out with

(ns pbvm-admin.core
  (:require
   ["dart:core" :as dc]
   [pbvm-admin.blue :as bt]
   ["ble.dart" :as bb]
   ["package:flutter/foundation.dart" :as foundation]
   ["package:flutter_blue_plus/flutter_blue_plus.dart" :as
    ble]
   ["dart:async" :as async]
...etc...
That fails on "Can't find Dart lib: ble.dart" I commented that out. Is that OK? Next, the app does not find any bluetooth devices, but then I also see that scan! and repl-ish do not run. Maybe we can pair at some point to get this going? I did hack things to call scan! from main, but that had other issues. I will explore that again, and if that does not pan out go for a less authentic recreation just so we can see MX working or not.

kennytilton 2022-12-17T19:43:35.070069Z

@zenflowapp ^^^

Benjamin C 2022-12-17T20:08:13.563189Z

@hiskennyness Oh, yep, ble.dart was a prebuilt example, guess I never checked that into git, but not needed or relevant currently. > Looks like you know your way around Dart futures. Not really, that tidbit was thanks to the DartClojure translator ;). That being said, I do think that would work for stubbing out the ble library. > Next, the app does not find any bluetooth devices, but then I also see that scan! and repl-ish do not run. Oops, sorry, yeah that is more dormant code. Right now I'm using the little plus button to trigger the scan.

Benjamin C 2022-12-17T20:10:40.227049Z

If you wanted to have it scan on every reload, you could add a (widget m/Text "") somewhere in the active tree. That would cause repl-ish to run on every hot reload.

Benjamin C 2022-12-17T20:12:34.600569Z

I'm game for pairing at some point. Although I can't say I've ever done that before, so I'm not sure what tech is ideal for that. I do have rustdesk installed.

Benjamin C 2022-12-17T20:14:34.257589Z

For bluetooth to show up, you need to manually turn on bluetooth and location services. Although I have not tried on Apple, more config might be needed there.

kennytilton 2022-12-17T20:15:46.081199Z

I think we can use google hangouts or sth. I am not much of a pairer either. Tech interviews with coding really bug me. 🙂 Lemme see how hangouts works.

kennytilton 2022-12-17T20:20:49.276119Z

Ah, they want us to use google chat now. I need your email to send you an invite.

Benjamin C 2022-12-17T20:21:11.114409Z

Sure, it's <mailto:ben@devcarbon.com|ben@devcarbon.com>

kennytilton 2022-12-17T20:23:19.334529Z

Ah, this should do it: http://meet.google.com/hye-auqr-gyf

kennytilton 2022-12-17T20:25:39.953809Z

Looks like you connected.

Benjamin C 2022-12-17T21:40:05.168819Z

Pushed changes to huh . Ought to have renamed that to aha :P

kennytilton 2022-12-17T21:49:17.012179Z

Hey, check out as-dart-callback:

(defmacro as-dart-callback [[& cb-params] & body]
  `(tiltontec.flutter-mx.core/with-ctx+as-is [~'me ~'ctx]
     (fn [~@cb-params]
       (tiltontec.cell.base/with-mx-isolation
         ~@body))))
Forgot I did that! 🙂

Benjamin C 2022-12-17T22:02:22.097249Z

Ah, cool! I remember now reading that and wondering what it did. :P For some reason in my mind I was thinking it was only relevant for widgets. Probably thought it only mattered when context was needed.

Benjamin C 2022-12-17T22:03:14.871609Z

Hmm, maybe there is a way to detect when a change is being triggered from a vanilla fn as a callback and warn about it?

kennytilton 2022-12-17T22:11:21.110669Z

🤔

Benjamin C 2022-12-18T03:59:28.429339Z

This look kosher to you? I see the :!!!-Do-I-even-run????!!!! and the service print out, but the watch never runs.

Benjamin C 2022-12-18T04:00:46.206979Z

Oh forget the :emphemeral? true , I added that but haven't tested it yet.

Benjamin C 2022-12-16T22:50:35.122239Z

Benjamin C 2022-12-16T22:55:14.042049Z

Problem I'm running into is that even though I have verified that the child device matrix has properly had its :connected? property set to true, :connections is still empty (on the parent matrix).

👀 1
Benjamin C 2022-12-16T22:57:10.334079Z

Perhaps this is not kosher?

:connections (cF (let [devices (mget me :device-candidates)]
                      (filter (fn [device]
                                (mget device :connected?))
                              devices)))

kennytilton 2022-12-16T23:00:57.387499Z

Hang on, checking sth simple...

kennytilton 2022-12-16T23:03:45.158229Z

I see:

(with-cc (mset! me :scan-candidates candidates))
The first parameter to with-cc s/b a throwaway debug value you might use for debugging. I will make a note to enforce keyword? on that. Not sure if that will help. Still reading.

Benjamin C 2022-12-16T23:04:38.208049Z

Oh, that might solve two-for-one!

kennytilton 2022-12-16T23:04:50.676489Z

So (with-cc :set-candis (mset! ....etc ))

kennytilton 2022-12-16T23:14:39.892559Z

That snippet looks fine:

:connections (cF (let [devices (mget me :device-candidates)]
                      (filter (fn [device]
                                (mget device :connected?))
                              devices)))
My one thought is that the devices are MX models, and they will occupy vectors in two slots. That's fine, but when we get to finalization we (I) will need to sort out ownership.

Benjamin C 2022-12-16T23:21:34.248749Z

Okay, so just tried again with the debug keyword passed to with-cc, and no change as far as :connections goes. (havn't tried replacing my temporary state atom yet)

kennytilton 2022-12-16T23:22:07.648699Z

Oh, let me look back at what you said about those.

Benjamin C 2022-12-16T23:23:22.702449Z

Printing the first :device-candidates gives this:

{:host nil, :parent Instance of 'Atom', :status BluetoothDeviceState.connected, :device-id 48:23:35:0C:1E:87, :cells-flushed ([:device-name 25]), :manufacturer-data {43981: [0, 0, 1, 12]}, :connected? true, :device BluetoothDevice{id: 48:23:35:0C:1E:87, name: PBVM, type: BluetoothDeviceType.le, isDiscoveringServices: false, _services: [], :device-name "PBVM"}
Where you can see that connected is properly updated to true

kennytilton 2022-12-16T23:25:10.877529Z

Ah, still reading, but we might need to deal with async, right? I am thinking the connections filtering runs before the candidates get their :connected property set. Hmmm, but then the state change would propagate. Still reading...

Benjamin C 2022-12-16T23:26:12.804609Z

printing :connections gives empty list (). Yep, 'tis async. I'll see if I can reproduce on a smaller scale.

Benjamin C 2022-12-16T23:28:42.209989Z

Just really quickly first though, is there a chance that because I'm manually pulling in a list of matrixes that the calculation of changes isn't happening?

Benjamin C 2022-12-16T23:28:59.575479Z

matrixes -> matrix kids

kennytilton 2022-12-16T23:29:06.544689Z

Where do you pull manually?

Benjamin C 2022-12-16T23:30:15.497859Z

Hmm, manually would not be the right word, I s'pose. Meant instead of navigating there with fx* and/or friends

kennytilton 2022-12-16T23:30:51.492659Z

In the connections rule, can we put a print statement of the devices right after they are bound in the let?

Benjamin C 2022-12-16T23:32:32.754019Z

Sure thing

kennytilton 2022-12-16T23:33:31.335099Z

Do you think I could run this against my bluetooth devices over here? I'd love to pitch in, no charge.

kennytilton 2022-12-16T23:35:31.940029Z

Lessee, the connections will depend...hang on. Can we add a DOALL on the filter? Lazy is the bane of MX! 🙂

kennytilton 2022-12-16T23:36:38.285289Z

We need a print in the filtering function as well, so we know it is actually hitting the :connected? properties.

Benjamin C 2022-12-16T23:37:47.740949Z

Ah oooh okay

Benjamin C 2022-12-16T23:39:07.531079Z

I do wonder if there isn't a better way to isolate the bluetooth interop IE make it stub-able for tests etc

kennytilton 2022-12-16T23:41:18.321589Z

We can also make the connections formula a :

(cF+ [:watch (fn [_ _ _ _ cell]
                         (dp :connections-used (tiltontec.cell.base/c-useds cell)))]
     ...etc...)

kennytilton 2022-12-16T23:42:00.083619Z

Yeah, I was thinking stub, too.

kennytilton 2022-12-16T23:43:12.279209Z

What we want to see is that the let picks up the devices you expect, and that the formula useds includes the connected? cells of each.

kennytilton 2022-12-16T23:45:21.640549Z

Sometimes I wrestle to get lazy lists realized. Not sure DOALL has always worked for me. Maybe I was just thrashing.

kennytilton 2022-12-16T23:47:21.183189Z

I see gen-device-mx does a mapv, that shouldn't be lazy.

kennytilton 2022-12-16T23:48:46.831129Z

Ah, OK, the-kids does a DOALL. I guess I developed trust in that at some point. 🙂

kennytilton 2022-12-16T23:54:56.983619Z

btw, as each device's :connected? property changes, the :connections rule will re-run and all the candidates will get scanned. No harm.

Benjamin C 2022-12-16T23:55:22.623359Z

Sorry for the delay, I've got some really weird thing going on, so I just restarted EVERYthing.

kennytilton 2022-12-16T23:56:05.968309Z

np. Don't mind me. I know you are busy. I'll just throw things over the wall as I spot them.

Benjamin C 2022-12-16T23:56:16.334819Z

> btw, as each device's :connected? property changes, the :connections rule will re-run and all the candidates will get scanned. No harm. This is what I expected, but doesn't seem to be happening.

Benjamin C 2022-12-16T23:56:20.941769Z

Thanks :)

kennytilton 2022-12-16T23:57:22.182779Z

I would try the print statements to be sure what we think is happening is happening. Might be a surprise in there.

Benjamin C 2022-12-16T23:59:09.707719Z

Okay, so it prints while scanning no problem. But it does not print under :connections after the device matrix is updated.

kennytilton 2022-12-17T00:00:13.488049Z

Does the print after the LET in the connections rule ever fire?

Benjamin C 2022-12-17T00:00:15.182469Z

Which gets triggered from the .listen in here:

(defn gen-device-mx [scan-candidates]
  (mapv (fn [^ble/ScanResult sr]
          (let [^ble/BluetoothDevice device (.-device sr)
                device-mx (md/make
                           :device (cI ^ble/BluetoothDevice device)
                           :device-name (cF+ [:watch (fn [_ me new-value _ _])]
                                             #_ (.-name (mget me :device))
                                             (.-name device))
                           :manufacturer-data (cI (.-manufacturerData (.-advertisementData sr)))
                           :device-id (.-id device)
                           :status (cI nil
                                       )
                           :connected? (cF (let [status (mget me :status)]
                                             (= ble/BluetoothDeviceState.connected status))))]
            (.listen (.-state device)
                     (fn [state]
                       (mset! device-mx :status state)))
            device-mx))
        scan-candidates))

Benjamin C 2022-12-17T00:00:33.979549Z

Yes, but only while scanning. IE before connection

kennytilton 2022-12-17T00:01:14.187769Z

When it prints does it show N devices?

kennytilton 2022-12-17T00:03:00.765909Z

Note that the population of :device-candidates will not change again, so we need the state flow from the :connected? dependencies to trigger the :connections formula again.

Benjamin C 2022-12-17T00:03:16.516479Z

Oh, the watch print never triggers. Guess that's to be expected given :connections doesn't currently update.

kennytilton 2022-12-17T00:03:55.993109Z

Which watch?

Benjamin C 2022-12-17T00:04:17.871849Z

> Note that the population of :device-candidates will not change again, so we need the state flow from the :connected? dependencies to trigger the :connections formula again. Correct.

Benjamin C 2022-12-17T00:04:24.521099Z

The :conncetions one

Benjamin C 2022-12-17T00:04:47.432169Z

(cF+ [:watch (fn [ cell] (dc/print [:connections-used (cty/c-useds cell)]))] (let [devices (mget me :device-candidates)] (dc/print [:devices devices]) (doall (filter (fn [device] (dc/print [:device device]) (mget device :connected?)) devices))))

kennytilton 2022-12-17T00:05:34.920429Z

It should fire at least once, when the model is created and all formulas are forced awake.

Benjamin C 2022-12-17T00:05:51.332179Z

Oh probably does way back....

kennytilton 2022-12-17T00:06:07.391959Z

OK.

Benjamin C 2022-12-17T00:06:51.528379Z

Do you think it is because the mget (mget device :connected?) is under the filter higher-order-function?

🤔 1
kennytilton 2022-12-17T00:07:01.276659Z

Well then that print is worth finding, I think. It needs to show dependencies on the :connected?'s

Benjamin C 2022-12-17T00:07:55.028979Z

Aha, #{Instance of 'Atom'} let me deref that..

kennytilton 2022-12-17T00:08:02.054929Z

Did we get a DOALL around that filter invoking the HOF?

Benjamin C 2022-12-17T00:09:05.997599Z

Ya

kennytilton 2022-12-17T00:10:10.587369Z

Dependency tracking works by binding a special var to the cell that is running, so the mget inside the HOF should see that.

Benjamin C 2022-12-17T00:10:23.787549Z

Okay, here it is:

Benjamin C 2022-12-17T00:11:00.782729Z

^ from the :cadidates watch

kennytilton 2022-12-17T00:12:17.833109Z

Ah, looks like dependency only on -- guessing -- the list of candiadtes. Try (mapv tiltontec.cell.base/cinfo (c-useds cell)).

kennytilton 2022-12-17T00:13:05.908549Z

Oh, sorry, you printed the deref.

Benjamin C 2022-12-17T00:14:05.751159Z

[[:device-candidates "anon" nil ()]]

kennytilton 2022-12-17T00:14:31.197829Z

The value is (). So we never see the device candidates. Lemme stare at some more code.

Benjamin C 2022-12-17T00:14:58.973879Z

Okay. I'll work on a mini-ified version.

kennytilton 2022-12-17T00:15:53.651189Z

Does gen-device-mx get input scan-candidates?

kennytilton 2022-12-17T00:17:35.411609Z

tbh, I think we are better off adding prints to what we have. It does look correct, so a minified version will prolly just work. 🙂

kennytilton 2022-12-17T00:18:30.173199Z

We are good. We have established :connections never sees candidates. Does gen-device-mx?

kennytilton 2022-12-17T00:21:11.447049Z

I am starting to wonder if there is a flaw in my ephemeral? handling.

Benjamin C 2022-12-17T00:23:47.553529Z

Hmm. Yes, it does.

kennytilton 2022-12-17T00:24:02.312939Z

Aother thought: maybe lose the the-kids in :device-candidates formula. Should be OK, but I have never done that.

kennytilton 2022-12-17T00:27:36.175999Z

We might also do a watch on the :device-candidates formula to see the new value.

Benjamin C 2022-12-17T00:42:00.246629Z

Okay, so :device-candidates updates during scanning, but not when it's child matrix gets updated later via connection.

Benjamin C 2022-12-17T00:42:09.354989Z

IE the watch runs

kennytilton 2022-12-17T00:44:02.411199Z

That sounds nominal. :device-candidates gets populated once. After that each element then changes.

kennytilton 2022-12-17T00:44:52.093299Z

But :connections never sees the dev-candidates, so it never reads their :connected? properties.

kennytilton 2022-12-17T00:46:19.965029Z

We did see that :connections had a depenency on :dev-candidates, but saw nil. When :dev-candidates got populated, :connections did not run again.

kennytilton 2022-12-17T00:48:43.404729Z

Maybe have the watch on :device-candidates print out c-callers of the cell the way we printed c-useds?

Benjamin C 2022-12-17T00:48:59.516039Z

K...

Benjamin C 2022-12-17T00:54:18.748499Z

:callers [[:connections "anon" nil ()]]

kennytilton 2022-12-17T00:55:51.671489Z

Awesome. Hmmm... and the watch shows a new-value full of devices?

kennytilton 2022-12-17T00:59:40.892039Z

You know, I might be able to knock off a parallel recreation using a different async mechanism, if you would like me to wrestle this to the ground.

kennytilton 2022-12-17T01:00:38.876789Z

Have we removed the the-kids? I am just trying to reduce variables.

kennytilton 2022-12-17T01:01:24.756769Z

Oh, and maybe make it :ephemeral? false.

Benjamin C 2022-12-17T01:03:08.666639Z

Yep, no more the-kids.

Benjamin C 2022-12-17T01:03:10.412409Z

Okay

kennytilton 2022-12-17T01:03:47.045579Z

Hmmm, I would also arrange for the test function to start by making a new bluetooth model each time.

Benjamin C 2022-12-17T01:04:04.486399Z

And yep, seeing new-values full of devices

kennytilton 2022-12-17T01:05:07.128879Z

Great. I think the problem may be that we are re0using the same model, if I have that right.

Benjamin C 2022-12-17T01:05:22.542679Z

I've been doing numerous hot-resets, would that change that?

kennytilton 2022-12-17T01:07:02.903259Z

Lessee. Deos that :connected formula run each iteration? TBH, now that we are confused I would eliminate the hot restart thing as a variable as well.

Benjamin C 2022-12-17T01:10:46.728939Z

I presume you mean hot-reload?

kennytilton 2022-12-17T01:11:43.694939Z

At this point I do not trust anything. 🙂

Benjamin C 2022-12-17T01:14:09.009079Z

Good point :)

kennytilton 2022-12-17T01:14:34.185449Z

I do see some unorthodoxy in what we have. It looks OK but I am starting to fade. It might be better if I recreate this tomorrow. I also have some debug machinery at the cells level I can activate if the failure to propagate persists.

kennytilton 2022-12-17T01:15:47.042929Z

But I would begin by creating a function that instantiates a new bluetooth on each experiment. Then hot reload is fine, I think.

Benjamin C 2022-12-17T01:16:14.436519Z

Curious about what the orthodox version would look like, but by all means, do get rest when it is needed.

kennytilton 2022-12-17T01:17:08.283639Z

You are not far off! And I might have done the same, you seem to be on top of things nicely.

kennytilton 2022-12-17T01:17:36.444029Z

I just have to wrestle with it a bit.

kennytilton 2022-12-17T01:18:13.314359Z

My recreation will stay very close to what you have until I see what is going on.

kennytilton 2022-12-17T01:21:17.627029Z

Guessing this is how you test? (scan! :eager-connect true :target "PBVM")

Benjamin C 2022-12-17T01:24:53.045649Z

Yep, although :eager-connect not necessary currently

kennytilton 2022-12-17T01:24:57.869729Z

Would there just be one scan in the currrent setup? Or could another get kicked off.

Benjamin C 2022-12-17T01:26:08.281369Z

Manual, but I have only been doing one typically

kennytilton 2022-12-17T01:28:14.965999Z

Is :scan-results vestigial?

kennytilton 2022-12-17T01:28:53.497159Z

Looks like the test driver sets :scan-candidates directly.

kennytilton 2022-12-17T01:29:54.354429Z

Ah, it used to set :scan-results

kennytilton 2022-12-17T01:32:41.613729Z

I am wondering about initialization now. I wonder if that watch on :scan-results gets fired off and messes with things. I would ## out that guy if we can. (Note to self: document lifecycle.)

Benjamin C 2022-12-17T01:33:45.373409Z

Hmm, interesting!

kennytilton 2022-12-17T01:35:28.744139Z

If we had a fresh bluetooth each run I would not worry, because initialization would run and then a scan would set the scan-candidates.

Benjamin C 2022-12-17T01:35:38.699709Z

Yeah, scan results is because mostly I didn't know how to filter beforehand.. I think

kennytilton 2022-12-17T01:36:11.703029Z

So the scan-results watch could do its thing and be done, with no lasting harm.

Benjamin C 2022-12-17T01:36:23.863099Z

Some things have changed a bit as I was working around different problems. (working around instead of solving for the time being)

kennytilton 2022-12-17T01:36:49.585319Z

Understood. Sounds like programming. 🙂

Benjamin C 2022-12-17T01:37:56.305789Z

Haha yep! > So the scan-results watch could do its thing and be done, with no lasting harm. Yep, its sole purpose is to (potentially) filter by target

kennytilton 2022-12-17T01:38:47.340799Z

OK, I should be on this by noon ET tomorrow. Looking forward to it!

kennytilton 2022-12-17T01:40:08.728009Z

I also often have a 3AM shift... 🙂

Benjamin C 2022-12-17T01:41:17.341229Z

Okay thank you very much! I think I may have been too slow getting this on github to actually be helpful, but I sent you an invite to the repo.

kennytilton 2022-12-17T01:41:48.233819Z

Got it. Thx!

Benjamin C 2022-12-17T01:42:12.572909Z

most recent work on the huh branch :P

kennytilton 2022-12-17T01:43:32.943539Z

Ah, understood. huh is my last escalation before wtf.

kennytilton 2022-12-17T01:43:48.309349Z

But I spell it hunh

Benjamin C 2022-12-17T01:44:35.471129Z

Haha I almost wrote mine huhp since "?" are not allowed in branch names. :P

kennytilton 2022-12-17T01:45:45.590919Z

Very lispy!

kennytilton 2022-12-17T01:49:13.386699Z

OK, I am off to the pub. Can't wait to dig into this later. I will just build the same structure but without the bluetooth, using my favorite async lookup to simulate the connection.

Benjamin C 2022-12-17T01:50:13.395919Z

Alrighty, thanks again for all your help, it is greatly appreciated! :D