I’m curious about your thoughts on this idea: Glam...
# thinking-together
g
I’m curious about your thoughts on this idea: Glamorous Toolkit and Live Programming environments seem to essentially be REPLs that use modernized input and output technologies. Back in the 1950s, REPLs used the best I/O and interface tech they had back then - mostly text-based command lines because computers couldn’t do much else. But now, environments like Glamorous Toolkit make output look better with graphics instead of just printing text, and Live Programming environments have GUIs with interactive stuff like sliders to change things while the program is running. The only tricky part in designing modern REPLs seems to be figuring out how to keep things flexible while still working with strongly-typed, functional programming languages. Do you think I’m oversimplifying these modern programming environments? Am I missing something important about how they differ from traditional REPLs?
j
Sometimes pieces of the environment have an event loop of their own with which the coder can interact in a variety of ways. This is quite different from a 50s/60s-style REPL where there’s a single thread of execution.
g
Actually, I'm still missing something. How is the modern main-loop different from the 50s/60s idea? In the 50s/60s REPL, the code runs a main-loop, and serially, runs a little GUI each time through. In the modern stand-beside Live thing, the main-loop serially runs a little GUI each time through. The GUI code is embedded in the main-loop in the 50s/60s version, but is stand-beside in the modern version. The effect is the same, just the implementation details differ (slightly). In the end, either approach invokes a function(s) to change something at runtime. Only the presentation of the GUI is different. And the speed at which the main-loop comes around is faster today. ? @Jack Rusher
j
In the Smalltalk case, there are objects that can have their own threads of execution independent of the GUI loop. In the Lisp case, you can have running threads that are independent of the REPL loop. These threads can be doing various computations, passing messages to each other, &c, with the REPL allowing you to “talk” to them. Most music livecoders have multiple such threads of execution producing different streams of audio at any given time, for example.
k
I'd say the overall idea of these environments is the same as with the REPL of the 1950s: better feedback loops. As @Jack Rusher points out, this has literally led to more loops that users interact with. Glamorous Toolkit has a lot more concurrency than a Lisp REPL. It has even added quite a bit support for asynchronous execution to Pharo, the Smalltalk that it builds on. How much that matters depends a lot on what you are doing. For me, it's only a convenience because most of my work can be summarized as automated mathematics, meaning that timing doesn't matter except when it exceeds my patience level. But if you have interactive processes, or need to supervise concurrent execution, the difference really matters.
p
The only tricky part in designing modern REPLs seems to be figuring out how to keep things flexible while still working with strongly-typed, functional programming languages
Can you expand on this point? What do you want a strongly typed language to give you in a repl environment?
g
I can try to expand on this point :-). Please ask some more, if interested. https://programmingsimplicity.substack.com/p/on-repls?r=1egdky.
k
@guitarvydas I agree with you that type checkers ought to be add-on tools rather than part of a language. And I'd want my type checker to be moldable as well. But I have only once seen this approach implemented, in Shen, which is far from a mainstream language. Are you aware of other attempts to do this?
g
@Konrad Hinsen No, I haven't found any languages that satisfactorily split type-checking from implementation. I have seen many hints that it is a reasonable goal, e.g. lint, Ohm (not types, but locality-of-reference), Statecharts (not types, but locality-of-reference), Agda (which looks to me like it contains 2 syntaxes, types and implementation), having played with Prolog for inferencing semantics from diagrams, having worked on Y2K stuff which involved weekend-long inferencing runs to dig out semantic information beyond what is commonly referred to as "types", ML, etc.
k
@guitarvydas There indeed many verification and validation systems that are similar to static type checkers. But there is also one important difference: static type checking relies on syntactic features of the underlying language, so it requires some co-design of language and type checker even if the implementations are separate.
g
@Konrad Hinsen Yes, but that is not a good reason to sully the readability of code by conflating it with type annotations and v.v.. IMO implementation and typing are orthogonal concerns, hence, should be written in separate places. Denotational Semantics hangs actions off of syntax. There is no reason to force humans to DRY syntax patterns. Syntax is cheap, push this concept further and let the machine figure out how to join things. ... [example to follow] ...
k
@guitarvydas OK, we agree. Now let's convince language designers and implementers!
g
@Konrad Hinsen example, finally (Note that I shamelessly stole your phrase "Data Model" 🙂) [I seem to be batting 0.000 for explaining clearly what I mean, but, I would be glad to entertain further questions and requests for clarification]
k
Thanks @guitarvydas! And I certainly don't claim any rights to the term data model.