[HN Gopher] Software Mimicry
       ___________________________________________________________________
        
       Software Mimicry
        
       Author : BobbyVsTheDevil
       Score  : 58 points
       Date   : 2022-11-19 02:35 UTC (20 hours ago)
        
 (HTM) web link (www.hillelwayne.com)
 (TXT) w3m dump (www.hillelwayne.com)
        
       | arh68 wrote:
       | So are the birds mimicking the bees, or is it the other way
       | around? Maybe I'm just missing the point.
       | 
       | I mean, is int[] a mimic of ArrayList<Integer>, or vice versa? Of
       | course they're similar, of course they're different. Is "mimicry"
       | just a pejorative thing?
        
         | Smaug123 wrote:
         | A definition is given as literally the first paragraph of the
         | post.
         | 
         | > Mimicry is when software X reimplements at a higher level a
         | core feature of software Y. The produced facsimile has some,
         | but not all, of the same properties, enough to "look like" it's
         | the same thing but missing many of the nuances. This exists in
         | every kind of software. One language can mimic another, a
         | library can mimic a language, a database engine can mimic a
         | product, etc.
         | 
         | I don't see how your question even fits into that definition.
        
       | LAC-Tech wrote:
       | _In Design Patterns in Dynamic Programming, Peter Norvig notes
       | that strategies are just trivially replacable with higher-order
       | functions (HOFs)._
       | 
       | So that's where this trope is from! A few things:
       | 
       | 1. The "just replace it with a higher order function" thing
       | obviously falls apart when your strategy has multiple methods. In
       | which case, the FP programmer might be tempted to supply a record
       | where each field is a function, and maybe they want to close over
       | some shared implementation details and... you've just re-invented
       | objects, albeit memory in-efficient ones.
       | 
       | 2. In many languages that support OO, a higher order function
       | _is_ an object, same way a string is, or an Integer.
       | 
       | I might be being harsh here. Presumably Norvig wrote this in the
       | hey day of "OO flavoured" languages like C++ and Java being
       | completely dominant in industry. But in 2022 we can stop
       | repeating this tired trope.
        
         | Smaug123 wrote:
         | Isn't your point 2 exactly what OP said?
         | 
         | > I think it's more interesting to think of the GoF-language as
         | mimicking HOFs with the strategy pattern facsimile. The
         | strategy pattern reimplements HOFs as a code-level idiom.
        
           | LAC-Tech wrote:
           | No more than HOFs are mimicking objects.
           | 
           | It's two schools of thought - everything is functions & data,
           | or everything is objects & methods.
        
             | zasdffaa wrote:
             | Closures are implemented as objects under the skin, but
             | that doesn't make them equivalent conceptually to me. I
             | suppose it's down to syntax, after all if you ignore that
             | you can have anything you like in assembler, but it won't
             | feel very high level.
        
               | layer8 wrote:
               | Closures are a poor man's objects. Objects are a poor
               | man's closures.
        
               | zasdffaa wrote:
               | What's the "poor man's" stuff? Is there a better way I
               | don't know of
        
               | Jtsummers wrote:
               | https://wiki.c2.com/?ClosuresAndObjectsAreEquivalent
               | 
               | Comes from that koan.
        
       | spinningslate wrote:
       | Enjoyed this, as with most of Hillel Wayne's writing. One bit
       | that puzzled me:
       | 
       | > "Representation" is similar to mimicry, except it's about
       | encoding a data structure in primitives that aren't well-suited
       | to it. Examples would be representing a tree in SQL tables,
       | representing a matrix with nested arrays, or representing a graph
       | in json.
       | 
       | I can see the first two exampples (tree in SQL, matrix as nested
       | arrays) because there are limitations in the representation. The
       | last one though (graph in json) doesn't seem obviously limited.
       | 
       | Mathematically, a graph G=(V, E), i.e. a set V of vertices
       | (nodes) and a set E of edges between nodes. That has a direct
       | translation into json:                   {             "G": {
       | "V": ["v1", "v2", "v3"],                 "E": [["v1", "v2"],
       | ["v1", "v3"]]             }         }
       | 
       | Perhaps it's that each edge is encoded as a list? Or that lists
       | aren't sets, so there might be duplicates? Enlightenment
       | appreciated.
       | 
       | --
       | 
       | EDIT: fixed typo.
        
         | rzzzt wrote:
         | They are probably alluding to the tree-like structure of JSON
         | where you can't represent cycles without inventing a pointer +
         | identifier format first, and that is indeed not part of the
         | building blocks "JSON-the-language" itself provides.
         | 
         | This seems to be a direct continuation of the SQL example --
         | wouldn't you be able to represent a tree with eg. tree paths
         | stored for each item?
        
         | tomwojcik wrote:
         | Emphasis on "aren't well-suited to it", I guess. It gets
         | complicated once you want to parameterize each node.
         | 
         | For the past year or so I've been "typing graphs" into YAMLs.
         | It's definitely doable, but hard to follow, especially with
         | cyclic graphs.
         | 
         | N8N is a very popular nocode workflow builder with a great UI.
         | They store workflows (graphs) as JSON. I use this complicated
         | workflow https://n8n.io/workflows/1534-back-up-
         | your-n8n-workflows-to-... in my homelab but I can't find a
         | public JSON representation of it. It'd be a great example of
         | how to present a complicated graph. I'll add it as an edit if I
         | find it.
         | 
         | EDIT: I found one public workflow backup on github.
         | https://raw.githubusercontent.com/thethanghn/n8n-workflows/d...
         | 
         | It's not that bad.
        
         | enriquto wrote:
         | > That has a direct translation into json:
         | 
         | Sure, but this representation is horrific, and a very clear
         | example of why json is not the appropriate format to store
         | graphs. A more natural format for graphs would replace your
         | punctuation-ridden monstrosity with a simple text file, for
         | example:                   v1 v2         v1 v3
        
           | spinningslate wrote:
           | I take your point, though you're not directly comparing like
           | with like. I'd used a literal translation of (V, E) so listed
           | vertices explicitly as well as edges. Using implicit
           | representation (as you have), the json could be simplified to
           | [["v1", "v2"], ["v1", "v3"]]. Still more syntax, definitely.
           | But not far off, for example, the graphviz[0] equivalent in
           | syntax overhead terms:                   graph {
           | v1 -- v2;             v1 -- v3;         }
           | 
           | To be clear, I'm no apologist for json. It just seemed to me
           | there was a pretty direct representation. @rzzzt's
           | observation on json being predominantly hierarchical and
           | therefore tree-shaped seems like the most likely reason
           | behond the original statement.
           | 
           | --
           | 
           | [0] http://graphviz.org/
        
       | reuben364 wrote:
       | For the StrategyWithSetup example, my FP oriented brain would
       | create another function:                   withSetup :: IO c ->
       | IO d -> (a -> IO b) -> a -> IO b         withSetup mc md f = \ a
       | -> do           mc           b <- f a           md
       | return b
       | 
       | Which is pretty identical except with a closure over functions in
       | place of a class of abstract methods. Classes with abstract
       | methods are effectively higher order functions, except
       | differences in boilerplate.
       | 
       | Another thing worth mentioning are language features that can't
       | be implemented unless you effectively implement a DSL like
       | automatic differentiation, call-cc, algebraic effects.
       | 
       | Hooks in React are sort of like a poor man's algebraic effects.
       | It can't affect the control flow so it relies on immutability and
       | hooks to unconditionally run to operate.
       | 
       | EDIT: after a bit of thinking, I realize that the unconditional
       | ordering of hooks is really a way to identify call sites at
       | runtime, which I don't think is related to algebraic effects.
        
       | samsquire wrote:
       | I called this idea of deliberately applying software mimicry as
       | branching libraries in my ideas document (link in profile (the
       | first link))
       | 
       | I experiment with programming language theory and designs as a
       | hobby and one of my thoughts is that the core underlying problem
       | of computing is an arrangement problem of a turing machine.
       | Compiling is "planning what you shall do". Execution is "doing".
       | We have the luxury of many ways of doing things in computing. But
       | it all seems to lead to mess of poor understandability and
       | complexity.
       | 
       | We're still trying to find the best way of doing things.
       | 
       | What am I trying to say? OOP inheritance hierarchy trees are
       | limited and not what you really want to do to represent your
       | problem. I want to define a situation or scenario and define what
       | should happen in that scenario. This is where asynchronous
       | programming and join calculus shines. I also like occam-pi's
       | select statement and golang's select. I also feel every computing
       | problem is the "expression problem" manifested. How do you
       | associate behaviour (what to do) with a type (a situation)? And
       | how do you define them so you don't have to reimplement all the
       | previously existing behaviours with the new thing?
       | 
       | The next section shall be reductive.
       | 
       | Ultimately all loops, function application, methods, expressions,
       | variables, classes, functions, lists, vectors, data structures,
       | algorithms exist as "things" in the imagination of the
       | developer's mind and the compiler. They don't exist in machine
       | code.
       | 
       | We have a grid of memory locations and the arrangement of things
       | in that grid is handled by a memory allocator. We also have
       | references in this grid as pointers, which form a structure of
       | their own. A turing machine.
       | 
       | Thinking of a type and behaviour as being solely one thing only
       | at a time is inherently limiting. I often want to see different
       | things "as" something else to talk about them in a slightly
       | different approach. A vector or ArrayList of objects of multiple
       | types but processed in the same approach, efficient compile time
       | polymorphism.
       | 
       | This is kind of how I imagine object orientated development to
       | really be about, I want to be capable of referring to an
       | arbitrary selection of objects and define new behaviours or
       | relations between the objects. Unfortunately most OOP ties
       | imperative behaviour and stateful manipulation to data rather
       | than modify exhibited behaviours of objects. Imagine being
       | capable of organising and managing load balancers and draining
       | them and devops architecture with code. A point and click GUI
       | where I can right click a load balancer and click drain. (I don't
       | mean code to bring them up or create them but to actually
       | administrate them with OOP)
       | 
       | I think the expression problem is a core problem of modern
       | computing and doesn't have an efficient solution.
       | 
       | We can decouple data structure, layout and algorithm.
       | Unfortunately most programming languages couple data structure +
       | layout (C) and OOP languages couple algorithm with layout.
       | Functional programming languages I'm not sure about.
       | 
       | I've been working with C++ templates recently with C++20
       | coroutines and multithreading and I am finding template
       | instantiation very interesting. I've been late to come around to
       | it.
       | 
       | This comment mentioned the insight that boxing and template
       | instantiation are related.
       | https://news.ycombinator.com/item?id=14764780
       | 
       | I am also working on a multithreaded programming language which
       | looks similar to Javascript. I use an actor implementation that
       | can send messages between threads.
       | 
       | https://github.com/samsquire/multiversion-concurrency-contro...
       | 
       | One of my programming language designs is the idea that every
       | line of code is a concurrent process and data flow is scheduled
       | by topological sorting. Iteration is handled automatically for
       | you. Every variable is actually a relation and algebraic
       | definition of relations between processes. This is called
       | algebralang. https://github.com/samsquire/algebralang
       | 
       | The idea is that you write the underlying insight into the
       | problem as an expression of what you want to do and let the
       | computer schedule the ordering or arrangement of operations to do
       | it. It's a form of pattern matching on the state of things
       | (objects in the system) and declaration of the desired result.
       | This brings to mind the rete algorithm (expert systems) and
       | differential dataflow.
        
       ___________________________________________________________________
       (page generated 2022-11-19 23:01 UTC)