You are viewing archived messages.
Go here to search the history.

Paul Tarvydas 2023-04-18 09:43:32

Drawware using - recent submission to Handmade Jam that I was involved with

📝 Odin0D

Kartik Agaram 2023-04-24 05:33:57

Where does the string "hello world" come from when you run the program?

I went back and reread your earlier writings (seeing running code often causes me to focus on a thing). Some reactions:

  • Components include two concerns: what code runs inside them, and what queues are wired up to them. I think having to duplicate the code inside every time you clone a component is a non-starter. You say, "deduplicating code is a compiler concern" ( which feels handwavy. Compilers are rocket science, and if we don't have the compilers to do this (we don't have compilers to do a lot, and it isn't obvious to me that compilers can deduplicate arbitrary code without risking lots of performance regressions ) then somebody still has to do it.
  • As a consequence it seems to me that components are strictly higher level than functions. You don't want to put raw code inside components. Stick a function call into the component, and now copying the component is cheap and you don't need a complicated compiler to make it cheap. This is fine. I wouldn't get too hung up on this. Like you said, use both. The interesting question here is when we should wrap a function in a component abstraction.
  • Calling these things zero-dependency is not quite accurate. As you define it, hardwiring the name of a function call is a dependency. But you have names of components like echo hard-wired into your example. Again, this is fine. I wouldn't get too hung up on this. The technical idea is sound. You just need a better name and positioning to avoid these distracting quibbles and focus the audience's attention on the core idea.
  • Request for example #1: How might you perform dependency injection with components? Pass something into a port that causes a component with that name to be invoked? Does this help make things more decoupled? Dependency injection does help decouple functions.
  • Request for example #2: Check out the example of run-length encoding at I'm curious how this program would look with your approach. Might you need coroutines? A component can have multiple inputs and outputs in parallel. Can it have multiple outputs in series ? So that pumping in one input results in multiple outputs? Then this question has me wondering if it should have multiple inputs in series as well. What might that mean?
  • You've mentioned before that this looks like hardware. One challenge with designing hardware circuits is getting just right the timing of signals coming into a piece of combinatorial circuit, and debugging the weird errors when we don't. We need the sequential latches just so to make the circuit more robust. But the latches add latency. I wonder if your approach shares this problem. What are the semantics of a component with two inputs that receives a signal/value on only one of them? You could block and wait for the other, or not. Both seem to have trade-offs, and I think I can construct subtle bugs both ways.
  • There are still some gaps before this can be the notation for concurrency. As you said, you need both functions and components to coexist. And you need a way to go between them: wrap a series of function calls in some queues to turn it into a component, or wrap a set of components into a function so you can give it a name/address to combine with multiple sets of queues. Functions provide abstraction. Copying components does not.

On the whole, this needs a whole lot more examples. I'd forget the tooling initially and just hand-write a bunch of examples. Do they seem clear? Are there notational changes that might make them clearer? Etc.

Paul Tarvydas 2023-04-18 09:43:50

Visualizing Text - recent submission to Handmade Jam that I was involved with

📝 Slider

Mariano Guerra 2023-04-20 12:12:41

GlooData demo on how to use ChatGPT to provide domain specific assistants in NoCode tools

  • Create cron-like schedules, check upcoming times

  • Generate & run a SQL query using the db schema as context

  • Scaffold JSON-like data

  • Build & preview rich Slack messages

Jimmy Miller 2023-04-21 19:36:29

When we ask questions like:

  • Should we use static or dynamic types?
  • Should we practice TDD?
  • Should we do agile development?
  • Should we use a memory safe-language?

People often say that the correct answer to all these questions is just to look at what the research shows. If research shows these things are good, then we should use them, if not, then not. In fact, this sort of response can be used to rebut almost anything we want to explore in the future of coding community. Why are we so interested in "X" if "X" hasn't been shown to be better via research? This sort of response has always bothered me. So I wrote a blog post on that question.

Konrad Hinsen 2023-04-22 08:16:49

In addition to all these arguments, it's worth considering that empirical research in software engineering is still far from a mature science. It's in a similar situation as nutritional science: a lot of (seemingly) applied research is done from a desire for answers that can be turned into advice, but there is no solid foundation from fundamental research. For example, nobody has a clear idea of which aspects of context matter for studying a given question, so there can be no carefully analysis of confounding factors.

Kartik Agaram 2023-04-22 03:02:31

I just published a little app to draw graphs:

I've wanted something like this for a long time. Intended for small graphs where laying things out by hand is not too painful, and it's nice that things don't move around every time I make a change, as happens with graphviz ( The file format is also amenable to git; no long lines, and adding new nodes or edges doesn't reorder unrelated nodes and edges.

Immediately after sharing it, I notice that there's also a limit on the number of edges. Too many edges, and the dumb layout algorithm (connecting centroids of nodes) starts to creak.

📷 snap.gif

Paul Tarvydas 2023-04-22 03:27:16

“t’s nice that things don’t move around every time I make a change’ == UX

Paul Tarvydas 2023-04-22 03:28:38

suggestion: Drop code, say Python, into the boxes, hook the boxes up with 0D ==> Programming Language.

Kartik Agaram 2023-04-22 03:34:36

I built it by dropping Lua into boxes 🙂

Not 0D, though, it's been on my mind to look more carefully at your recent projects.

Konrad Hinsen 2023-04-22 08:23:55

I guess the "export" function is "screenshot"? Which I think is perfectly fine for this type of application. Though I wish graphics platforms systematically had "save as SVG" for whatever is drawn in a window.

Kartik Agaram 2023-04-22 08:25:58

Yeah, no reason it couldn't. has SVG export, should be easy to port over.

Paul Tarvydas 2023-04-22 09:28:26

The difference between boxes drawn by normal humans and boxes drawn by programmers is decoupling.

Normal humans draw boxes that are asynchronous (e.g. boxes drawn on a whiteboard), programmers draw boxes that are synchronous (which leads to hating VPLs).

Rhetorical questions: Can Queues (LIFO) be created in Lua? Does Lua have anonymous functions (closures/whatever)? If so, then full decoupling (which I call 0D ATM) is easy. :-)

One more step: create 2 kinds of boxes: (1) code and (2) routing. Boxes of type 2 (Containers) are recursively defined - they can contain boxes of type 1 or type 2. In Lisp, type 1 boxes are called Atoms and type 2 boxes are called Lists. In my vocabulary, 1=Leaf, 2=Container.

Ulysses Popple 2023-04-22 17:46:12

For I went with autolayout only. To make that possible, it's got a tree structure - nodes have multiple inputs but only one output. This mimics some good programming practices too, so it works well.

Kartik Agaram 2023-04-22 22:52:08

That's cool! I poked at autolayout for an earlier app: I may well do more with it.

Paul Tarvydas 2023-04-23 02:35:09

Auto Layout Is A UX Disaster

IMM, auto-layout results in disastrous UXs.

There are two kinds of code:

  • code for controlling machines, code that is machine-readable
  • code for communicating to human readers why code for controlling machines has been written the way it was - DI, Design Intent. Code that is human-readable.

When laying out code for DI - human consumption - spatial relationships matter. Do you want power-assist to help you lay out spatial relationships? Yes. Do you want power-assist to change the layout every time you make a change? No.

When laying out code for machine consumption, spatial relationships don’t matter. Current electronic machines (aka “computers”), work only with sequential relationships. Spatial layout doesn’t matter to machines. Auto-layout applied to this kind of code is just a waste of electrons.

Summary: layout only matters to human readers. Human readers grok things that are laid out spatially. Each time the layout changes, human readers need to expend brain-power to re-grok what’s being presented. Brain-power is bounded - users can burn brain power to think, or, they can burn brain power to re-grok what they’ve already grokked.

Ulysses Popple 2023-04-23 11:01:33

Paul Tarvydas have you given nodysseus a go? Here's a tutorial showing a bit more of the autolayout behaviour.

Ulysses Popple 2023-04-23 11:03:14

I agree that spacial layout is only useful for human readers - and autolayout means that no spacial information is saved in the data structure of the graph.

Ulysses Popple 2023-04-23 11:11:32

In my experience, relayout when adding nodes is confusing if it cuts from layout A to layout B (like autolayout in touchdesigner or houdini). However, using d3-force for graph layout means that nodes can (somewhat) organically transition from layout A to layout B. The main layout problem I haven't solved yet is that between refreshes the graph can sometimes be laid out differently. It's usually fairly similar, especially if the graph stays the same as randomness is seeded by graph structure, but sometimes after editing a bunch and refreshing subtrees swap places. In those cases it takes a sec to orient to the different parts of the graph, but search is there to help. I'd argue the time/brain power spent regroking the layout is less than the time and brain power spent creating a meaningful layout manually (I and many other TD/Houdini/unity devs I know spent countless hours rearranging graphs where "power assist" autolayout hurt more than it helped), and for sure more human-centric than a large text file.

Kartik Agaram 2023-04-23 14:36:42

There's nothing intrinsic to autolayout that requires layout to change every time you add/remove a node. As an obvious example, you could add the existing positions of all existing nodes as constraints to the solver. Perhaps this over constrains the problem, but I think it's under studied.

Paul Tarvydas 2023-04-22 22:23:21
Timothy Johnson 2023-04-23 05:00:16

I think Scratch works a little like your proposal, right? Instead of function calls, messages are broadcast, and every object can respond.