• Kartik Agaram

    Kartik Agaram

    2 years ago
    I've been noodling for the umpteenth time on a representation for programs that reduces the need to "play computer". My post last night on #two-minute-week (https://futureofcoding.slack.com/archives/C0120A3L30R/p1600587602007800) triggered enough unexpected thinking together to get me to write up my recent attempts and try to trigger more. We all simulate programs in our heads. The activity seems to break down into two major use cases:* Forward path: Extracting functions out of arbitrary computations. * Backward path: Imagining the execution of arbitrary computations containing function calls. The forward path fits very well with ideas like starting with concrete examples and emphasizing data at all times. Nobody should ever have to start with a function definition. Instead, start with an example computation like:
    18 * 9/5 + 32
    , and incrementally end up at a function like
    celsius-to-fahrenheit
    . The backward path fits with various metaphors for debugging programs. Debug by print, debug by step, time-travel debugging. A key concern is how to uncoil static computations (loops, recursion) into dynamic metaphors (traces, stack frames, interactive movements). Postfix expressions fit beautifully with the backward path. As the demo of Brief (

    https://www.youtube.com/watch?v=R3MNcA2dpts

    ) showed, execution is already quite uncoiled, with no backward jumps. While the Brief demo didn't show it (it's easy to spot where the presenter plays computer in their heads), it's reasonable to imagine a way to drill down into function calls, replacing words with their definitions. By contrast, conventional expressions -- tree-shaped and using names -- immediately throw up impediments in understanding what happens first. However, the forward path is thornier:1. It's common to claim that point-free programs make it easy to factor out new definitions, but that's only true when the definition consists of consecutive words. Consider how you would go from
    * 3 3
    to a definition of
    square
    , or from
    3 4 + 5 *
    to a definition of
    (a+b)*c
    . 2. After they're extracted, point-free functions are harder to understand. What does the stack need to look like at the start? How many words, what types, how many words consumed, all these questions require simulating programs in your head. Or a manual comment. This was the idea maze in my head until I saw LoGlo (https://loglo.app/2020-06-16). The cool idea here has taken me weeks to articulate: lines have names and get separate stacks. Forth typically writes to names within lines with words like
    !
    . Limiting definitions to one per line strikes me as an advance. And having names gives us a way to make Forth words less point-free. I start imagining flows like turning
    * 3 3
    into
    * x x
    using two 'rename' operations, and then turning the entire line into a new function. Like, imagine a UI with a code side on the left, and a scratch computation on the right:
    │
                  │  x: 3
                  │  * x x
    After defining a function it might look like this:
    │
       : sq x     │  sq 3
            * x x │
                  │
    Notice how the definition of
    x:
    above gets replaced by the call to
    sq
    below. That's kinda pleasing. But there's issues. This manipulation requires modifying definitions of free variables. Worse, I ended up with the function call in prefix order. Trying to make things consistent got me stuck up on a tree with a 2D layout until I noticed I'd lost the benefits of postfix that got me on this road in the first place. I'll include it here just in case it sparks ideas for others, but I'm starting to think it's a dead end. Anyways, that's where I am, still looking for a representation that's easy to uncoil and where inlining function calls is a 'smooth' visualization.
    Kartik Agaram
    g
    +3
    29 replies
    Copy to Clipboard
  • Gray

    Gray

    2 years ago
    Have there been similar approaches to this style of formatting?
    Gray
    Kartik Agaram
    +3
    12 replies
    Copy to Clipboard
  • w

    Will

    2 years ago
    A big issue in programming is that a program is an extremely lossy record of history. Even with good comments, it’s hard to look at a program and know: • What are the alternatives that were considered, but ignored? Tried, but later discarded? • What order was this program written in? Is a particular line or function the focal point of this code? • What is the set of resources the author used to write this code? • How weathered is this code? How many bugs have happened in this code? How scared should I be to change it? What are some ways in which programming environments could help us record this info / answer these questions without requiring additional effort from the author?
    w
    Kartik Agaram
    +7
    38 replies
    Copy to Clipboard
  • Srini K

    Srini K

    2 years ago
    I’m a data scientist by background, and a lot of this PL stuff is new to me. However, I think data science is an interesting use case for innovation in PL. The most common use cases are a bit more bounded and well defined, the persona base ideal (people who just wanna do data stuff, not program), and there’s a non-PL success here already (Excel!). • Are there others that are motivated by this data science use case / working on it? I know Instadeq is here, I’m sure there are many others. I’ve chatted with Erik Blakke about his Ultorg system. • Why haven’t we seen a good live programming language for data science? It’s so ideal for it! Everything from sampling / streaming in data results to keep things live to the fact that data analysts / scientists want to move / iterate at the speed of thought, and most of data science is this type of curiosity driven stumbling around the data-dark
    Srini K
    Mariano Guerra
    +12
    57 replies
    Copy to Clipboard
  • l

    larry

    1 year ago
    I don't really understand Roam, although it is favorably mentioned here frequently. I tried a couple of videos but quit after 15 minutes when all they've demod is linking between notes. It seems like watered down NoteCards, with a (really) nice UI. Everyone here is probably familiar with NoteCards but if not, the first two linked papers are very good. https://en.wikipedia.org/wiki/NoteCards
    l
    e
    5 replies
    Copy to Clipboard
  • Denny Vrandečić

    Denny Vrandečić

    1 year ago
    Hi all! I am working for the Wikimedia Foundation where we are starting to work on a new project [1]: a wiki of functions (name is currently being discussed by the community) [2]. Imagine that for every function, you have on wiki page, where the wiki page describes what the functions does, it's formal parameters (input types, output types), etc. Each function can have several implementations associated with it (which can be built either from other functions in the wiki or be natively written in a programming language, and we plan to support many of those) and also tests. Maybe the best way to understand the project is to take a look at some of the early mockups. [3] The functions are meant to be functional, i.e. not to rely on state (well, not too much - they are able to call out to the Web, e.g. to look up information in Wikidata, etc., so in some way, the Web does provide state. We will need to figure that part out. There's a lot of open questions around that). The type system is also in the wiki, so that it is extensible by the community. We are in very early development (and, in fact, hiring!) [4] I am happy to answer any questions, but I would love to invite folks to join us, either for discussing the project, help working on it, or ask as hard questions and think about how to solve it. [5] A preprint paper with background can be found on Arxiv. [6] The paper has been accepted, but not published yet. Happy to answer any questions here, and to have discussions about what we are doing. In the future I expect us to have many questions like "what is a good exception system", "do we need a type hierarchy", "what should the UX for the project do", etc., so would love to have a place for that. [1] https://meta.wikimedia.org/wiki/Abstract_Wikipedia [2] https://meta.wikimedia.org/wiki/Abstract_Wikipedia/Wiki_of_functions_naming_contest [3} https://meta.wikimedia.org/wiki/Abstract_Wikipedia/Early_mockups [4] https://boards.greenhouse.io/wikimedia/jobs/2338515 [5] https://meta.wikimedia.org/wiki/Abstract_Wikipedia#Participate - links to mailing list, chat, etc. [6] https://arxiv.org/abs/2004.04733
    Denny Vrandečić
    Srini K
    +5
    25 replies
    Copy to Clipboard
  • Mariano Guerra

    Mariano Guerra

    1 year ago
    What's the future of side effects?
    Mariano Guerra
    Leonard Pauli
    +11
    29 replies
    Copy to Clipboard
  • a

    Andrew Carr

    1 year ago
    I'm not sure how to phrase this question. I've been thinking a lot about "bit rot" recently. For example, will we reach a point where there are no DVD players that can decode the disks? Or where there is no existing program to read PowerPoint presentations? Is this a likely eventuality for systems? Should everything be txt files to avoid this? Are we going to have our period of history with large gaps from this bit rot problem? Can we as programmers do anything to avoid this?
    a
    Denny Vrandečić
    +5
    9 replies
    Copy to Clipboard
  • w

    Will

    1 year ago
    I was reading Fred Kjolstad’s thesis (http://fredrikbk.com/publications/kjolstad-thesis.pdf) about compilers for sparse linear algebra. He says:
    The issue with libraries of hand-optimized functions boils down to our inability to easily build composable building blocks that perform well. Current sparse linear algebra libraries do not let us compose expressions, data structures, optimization strategies, and architectures without sacrificing performance. The first performance loss is from lost temporal locality—a deficiency that is also present with dense operations. Second, sparse operations may operate on many different data structures, which are each designed to work well on one type of sparsity pattern. If two composed functions do not support the same data structure, then it becomes necessary to perform an expensive conversion between irregular data structures. But the most serious issue is that composing two sparse linear or tensor algebra functions may perform asymptotically worse than a fused function written to compute the entire expression at once.
    This made me think more generally about the composability vs. performance trade-off. Being able to compose black box abstractions at a high level is at the very foundation of software engineering, enabling programmers to eliminate boilerplate and more easily use others’ work. Yet composition is the enemy of performance: a careful implementation that fuses two operations is often more efficient than a sequenced invocation of the two. However, most compilers today only offer
    #[inline]
    pragmas or other extremely shallow means of reducing abstraction/composition costs. Even the most advanced C++ template magic can’t do the necessary code-reordering to achieve the optimal composition that Fred describes. Several programming systems have good ideas in this direction: • Zero-cost abstractions in programming languages (eg Rust https://blog.rust-lang.org/2015/05/11/traits.html) • Separating algorithm from schedule (eg Halide http://halide-lang.org/) • Using higher-order functions to express data parallelism (eg Spark https://spark.apache.org/) Curious to hear others’ thoughts (how will we manage this trade-off in future langs/compilers?) and pointers to relevant work.
    w
    d
    2 replies
    Copy to Clipboard
  • Jason Hobbs

    Jason Hobbs

    1 year ago
    Do you know of any resources that attempts to outline the various things a developer holds in their head while working on task x?
    Jason Hobbs
    w
    12 replies
    Copy to Clipboard