Unimplemented Primitives

Jason Bertsche edited this page Jul 16, 2018 · 38 revisions

Assorted

  • inspect
    • Jason’s input: Work is already in progress on this on Tortoise’s wip-inspect and Galapagos’ wip-inspection-window branches. Mostly, it’s just UI stuff that needs to be implemented in Galapagos, at this point.
  • export-interface
    • Jason’s input: I took a shot at this. It didn’t go well. There’s no real easy way to write a DOM element to an image. There are libraries to do it, but, in my experience (as of August 2017), they’re pretty janky. I managed to use a popular library—maybe even two? I’ve forgotten...—to try and export interfaces. It succeeded. With the exception that things didn’t look right. Namely, sliders’ labels were shifted down, such that half or more of each letter was cut off. This rendered those labels mostly illegible. And, since I’ve got to assume that the whole reason you want to see the interface, rather than just using export-view, is because you want to see what all of the widgets are set to, that sort of bug largely negates the purpose of the primitive. Maybe the technology for this will get better with time. Or maybe people will become comfortable with just using their computer’s “Print Screen” button. ¯\_(ツ)_/¯
  • __set-line-thickness
    • Jason’s input: Another pretty pointless primitive. Don’t bother. Even Uri and the people on the NetLogo development team were surprised to learn that it existed

HubNet

  • Difficulty: Hard
  • Description: These prims are used in HubNet models. Implementing HubNet—a networked version on NetLogo—is no small feat. It's on our radar, but it will be quite a while before this functionality is ready.
  • Jason’s Suggested Solution: Spend a lot of time and implement it
  • Prims:
    • hubnet-broadcast
    • hubnet-broadcast-clear-output
    • hubnet-broadcast-message
    • hubnet-clear-override
    • hubnet-clear-overrides
    • hubnet-clients-list
    • hubnet-enter-message?
    • hubnet-exit-message?
    • hubnet-fetch-message
    • hubnet-kick-all-clients
    • hubnet-kick-client
    • hubnet-message
    • hubnet-message-source
    • hubnet-message-tag
    • hubnet-message-waiting?
    • hubnet-reset
    • hubnet-reset-perspective
    • hubnet-send
    • hubnet-send-clear-output
    • hubnet-send-follow
    • hubnet-send-message
    • hubnet-send-override
    • hubnet-send-watch

Synchrony-Plagued

  • Difficulty: Hard
  • Description: The import-* prims do file reads synchronously, so this is a problem if we want to import in the middle of a procedure and then, within that procedure do something with the result of the import. Since I/O happens asynchronously in JavaScript, those results won’t be there. Also, these prims needs to ignore that path argument they're given and open up a file dialog (which is unpleasant, but we're accepting that as a necessary evil.) The user has to manually select the file from a file dialog, or HTTP needs to be used (changing the semantics of the prim, and once again introducing some asynchrony). Moving on to the others, no-display only makes sense in the presence of display, while display and wait both require that we stop execution in the engine in order to “come up for air” and let the UI do stuff. We can pass in UI callbacks, but they don’t really matter, because the UI won’t actually update until there’s no JavaScript running (after the end of the procedure). The problem with user-one-of is that it is synchronous and stores its value into a variable, which is then likely used later on in the same procedure. There are several built-in synchronous dialogs in JavaScript (which we use for other user-* prims), but not one for this use case. We could build our own dialog, but only natively-implemented ones can be synchronous.
  • Jason’s Suggested Solution: We explored the idea of running the engine inside of a Web Worker, so we could allow the UI to “breathe” freely, and also simulate blocking threads when needed. This didn’t work out. The engine, when run inside of a Web Worker, was massively slower than when it ran in the UI thread (check out some single-worker benchmarks to see for yourself). As a result, it seems that Web Workers aren’t the solution. The only other reasonable solution that comes to mind to me to try using ES6 generators. It might be a bit yucky, but I expect that all of these prims would be expressible in terms of generators in some non-terrifying way.
  • Prims:
    • import-pcolors
    • import-pcolors-rgb
    • display
    • no-display
    • wait
    • user-one-of (does not have a JS equivalent)

ask-concurrent

  • Difficulty: Hard
  • Description: without-interruption can only be used with ask-concurrent. ask-concurrent is usually not very useful or intuitive. Since the introduction of ask, ask-concurrent has been highly recommended against. And implementing it with the correct semantics in NetLogo Web would be a pretty unpleasant, code-complicating task.
  • Jason’s Suggested Solution: Just don’t ever implement these
  • Prims:
    • ask-concurrent
    • without-interruption

File

  • Difficulty: Daunting, if not impossible
  • Description: These prims are used for reading and writing files. There are a number of problems that stand in the way of implementing these primitives. First of all, many of the prims seem to assume that we have file handles that we can open and close and stream data into at will. To my knowledge there is no ability to do that with JavaScript. Also, I/O in JavaScript happens asynchronously, so something that reads a file into a variable and then runs some NetLogo code using that variable—that sort of thing would not really be expressible in JavaScript without some serious compiler magic. Also, we can only automatically write files, and only to the user’s Downloads directory. To repeat that in summary, JavaScript cannot: do synchronous I/O, stream to a file, do automated reads from the file system, or automatically write to any place but the user’s Downloads directory. It’s possible that the problem could be solved by us building/using some sort of virtual file system in-browser, but Jason suspects that that would not go well in both development resources consumed and from the user experience perspective.
  • Jason’s Suggested Solution: It would be easier, probably, to just have things function differently and do reading/writing through HTTP GET/POST
  • Prims:
    • file-at-end?
    • file-close
    • file-close-all
    • file-delete
    • file-exists?
    • file-flush
    • file-open
    • file-print
    • file-read
    • file-read-characters
    • file-read-line
    • file-show
    • file-type
    • file-write
    • set-current-directory
    • user-directory
    • user-file
    • user-new-file

BehaviorSpace

  • Difficulty: Probably not too tough
  • Description: BehaviorSpace. It manages these values under the hood. It can expose them through the primitives mentioned below.
  • Jason’s Suggested Solution: You could probably just have Baby BehaviorSpace pass these values into the engine when it starts a run. Or you could pass in a prim config that just defers to a closure around a mutable variable that lives in Baby BehaviorSpace and gets altered as necessary.
  • Prims:
    • behaviorspace-experiment-name
    • behaviorspace-run-number