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

Yuriy Zymlex 2024-08-25 13:35:04

I have a few questions/topics about which I would like to get your opinion. Since I'm interested in the underlying logic of this things, this may look banal.

If the essence of every programming language is the construction of logic , have there ever been any attempts to bring that process __ into minimal separate entity for purpose of wider use than just programming?

By purposes, I mean the creation of:

  • Text instructions - as you can see them in Jira, Org-Mode, Markdown (or detailed program's log)
  • Graphical - MindMap or here it is good to remember "data flow diagrams" from informatics, but it can be expanded to any other kind
  • Actually programming itself, but as building any "pseudo" code (including graphical) for convenient use with a theoretical possibility of converting "pseudo" code back to logic
  • ... (other variants)
Tom Larkworthy 2024-08-25 18:55:54

en.wikipedia.org/wiki/Decision_Model_and_Notation? Its business logic definition that can be run on multiple engines and also has a graphical representation. cDMN adds constraint programming.

Yuriy Zymlex 2024-08-27 14:56:10

Tom Larkworthy Thanks for example!

logic definition that can be run on multiple engines

Are there no known adaptations for visual coding?

Tom Larkworthy 2024-08-27 15:07:16

check out camunda.com/dmn the DMN tables are assembled digramatically but the core is tabular text, BPMN can kinda do full graphicaly but with text labels? I am not sure what granularity you want, probably none of it is as as visual as you want but they all use some level of visual design canvas to assemble building blocks

📝 DMN Tutorial

What is Decision Model and Notation (DMN)? Get a DMN tutorial and introduction as it is defined in version 1.1 with an example decision table and decision diagram.

Guyren Howe 2024-08-28 05:35:23

I just had a thought.

Is anyone aware of any work on a non-programmer-friendly UI for editing pattern matching? Semantically, I’m looking for Datalog. So I guess a Datalog query UI, although I could imagine a pattern matching UI being developed outside of a use with Datalog.

Jarno Montonen 2024-08-28 08:42:32

I have been thinking about creating one with levlo.com, but not sure who would use it and for what reason.. Did you have an use-case in mind?

Ionuț G. Stan 2024-08-28 08:59:00

I've recently come across Query by Example (QBE), which seems related to what you're asking? en.m.wikipedia.org/wiki/Query_by_Example

📝 Query by Example

Query by Example (QBE) is a database query language for relational databases. It was devised by Moshé M. Zloof at IBM Research during the mid-1970s, in parallel to the development of SQL. It is the first graphical query language, using visual tables where the user would enter commands, example elements and conditions. Many graphical front-ends for databases use the ideas from QBE today. Originally limited only for the purpose of retrieving data, QBE was later extended to allow other operations, such as inserts, deletes and updates, as well as creation of temporary tables. The motivation behind QBE is that a parser can convert the user's actions into statements expressed in a database manipulation language, such as SQL. Behind the scenes, it is this statement that is actually executed. A suitably comprehensive front-end can minimize the burden on the user to remember the finer details of SQL, and it is easier and more productive for end-users (and even programmers) to select tables and columns by selecting them rather than typing in their names. In the context of information retrieval, QBE has a somewhat different meaning. The user can submit a document, or several documents, and ask for "similar" documents to be retrieved from a document database [see search by multiple examples]. Similarity search is based comparing document vectors (see Vector Space Model). QBE represents seminal work in end-user development, frequently cited in research papers as an early example of this topic. Currently, QBE is supported in several relational database front ends, notably Microsoft Access, which implements "Visual Query by Example", as well as Microsoft SQL Server Enterprise Manager. It is also implemented in several object-oriented databases (e.g. in db4o). QBE is based on the logical formalism called tableau query, although QBE adds some extensions to that, much like SQL is based on the relational algebra.

Paul Tarvydas 2024-08-28 09:04:15

I am unaware of such UIs, but, I have fooled around with slapping little DSLs together that combine Prolog and JS together in a markdown-inspired syntax using a bash script. An example of live code that I used:

# connection

## parameters

  Parent

  Edge

  Sender

  Receiver

## imports

  shapes

  names

  connection

## query

  das_fact(kind,Edge,edge)

  sourceof(Edge,Sender)

  targetof(Edge,Receiver)

  das_fact(direct_contains,Parent,Edge)

## display

das_fact(connection, ${Parent}, ${Edge}).

das_fact(sender, ${Edge}, sender{component:"${Sender.component}",port:"${Sender.port}"}).

das_fact(receiver, ${Edge}, receiver{component:"${Receiver.component}",port:"${Receiver.port}"}).

Why markdown? Because emacs then lets me collapse each section and imagine that these are layers.

[I would be glad to explain further, if this is of interest]

Guyren Howe 2024-08-28 16:19:38

I very much have a use case in mind: frest.substack.com/p/what-is-frest

Also, it just occurred to me that dataflow graph without loops is a really nice sort of construction. It would be a great way to present say a non-recursive Datalog query, or many other sorts of logic, in a manner that is friendly to non-programmers.

Even without the graphical presentation, a friendly presentation of the non-recursive part of Datalog would be cool.

But then, you can make it recursive, and present that in a stepwise fashion. Stepping between the same, or other, sets of pattern matches and conditions.

📝 What is FREST?

FREST is simpler computing for ordinary folks and programmers alike.

Paul Tarvydas 2024-08-28 18:54:49

I’m trying to figure out why you (Ivan Reese) think that using OhmJS to produce the wiki would create a dependency, while I (Paul Tarvydas) don’t think so. Here’s a diagram of how I understand the situation...

tonedown.png

Konrad Hinsen 2024-08-29 06:03:41

In such discussions, always make the distinction between runtime dependencies and build dependencies. Basic example: for a C program, gcc (or whatever other compiler) is a build dependency: you need it to create a binary, but then you can throw it away. But glibc (under Linux) is a runtime dependency: you must have it to run the compiled C program.

In your diagram, OhmJS is a build dependency for tonedown.py.

The main insight behind the latest generation of package managers (Nix, Guix) is that build dependencies matter just as much as runtime dependencies for auditable and reproducible provenance tracking. In your example, any change to the specs requires rebuilding tonedown.py, so OhmJS is an important dependency, even if it is not required every time someone changes a Wiki page.

Konrad Hinsen 2024-08-29 06:07:56

Of course, that also holds for programming languages, which Ivan Reese tried to play down yesterday. Compilers and interpreters can be nasty dependencies. Bugs and backwards-incompatible changes in them are a real pain. As an example, I see computational scientists slowly moving away from their pet language, Python, because they are fed up with the slow but steady stream of compatibility-breaking changes (in the interpreter and the foundational libraries) that make their complex programs return somewhat different results with each new version.

Konrad Hinsen 2024-08-29 06:15:11

So far for theory. In practice, some dependencies are more acceptable than others for pragmatic reasons. A C compiler is rarely critical: they tend to be stable, and there are lots of them. Stick to standard C and you can expect little trouble. Same for other standardized languages with multiple implementations (C++, Fortran, Common Lisp, ECMAScript ...).

Next are languages with only one major implementation, but backed by a team/community focused on stability. That covers Java, Clojure, and Lua, and possibly Ruby (which I don't know well).

Other uncritical dependencies are small convenience utilities that you could maintain yourself, or even rewrite if necessary.

There's of course another cost to dependencies: the cognitive effort for learning how to use them correctly.

Paul Tarvydas 2024-08-29 10:07:50

Thanks! I might add:

There is a third kind of dependency - hidden runtime dependency. For example ‘f(x)’ implies that the given lump of code can only be used in systems that supply a function called “f”. This (deeply) impacts multiple-use of the lump of code and testability of the lump of code. The lump of code cannot be tested in a test jig unless “f” is supplied or stubbed out, i.e. the unit of code cannot be considered to be a “component”. Hardware designs get this more right through the use of very independent / isolated ICs. Unit tests in hardware documentation tend to be more concise and focussed and meaningful than software equivalents. [The ensuing question "Why?" interests me].

The cost of learning how a system works before maintaining it. This includes understanding all dependencies in the system (runtime, compile-time, hidden) and all paradigms used in the system. I am of the opinion that this cost is greater than the cost of learning multiple notations and convenience tools that are used for building the system. I am drawn to emphasizing (a) reduction of this kind of learning curve (b) dividing and conquering this kind of information, allowing one to understand everything about only parts of the system before performing maintenance without any surprises. Hidden dependencies tend to oppose the dividability / composability of such learning. Fundamentally, you have to know everything about a system before making any changes, or, you end up playing whack-a-mole with unexpected gotchas that are triggered by your changes. I have formed the opinion that you can best fix this problem by starting out with isolated units instead of backing isolation in later. (Analogy: “How do you build a light airplane? Build an airplane, then, add lightness.” - an overly difficult approach which tends not to work).

Konrad Hinsen 2024-08-29 12:01:49

Why do you call this a hidden dependency? In statically linked binaries, it is very explicit: the linker will tell you "missing symbol f" if f(x) is missing. In more dynamic languages, the error message may be deferred to runtime, but it's still very explicit, as in Python's "NameError: name 'f' is not defined".

But I fully agree on the second part. In terms of cognitive load, it's not the number of dependencies nor the size of the codebase (dependencies included) that matters.

Paul Tarvydas 2024-08-29 12:39:24

Why do you call this a hidden dependency?

Probably because I haven’t found the words to express what I mean 🙂 . To me, ‘f(x)’ produces a mindset where it is OK to call outside of your “scope”, and, one tends not to even notice, i.e. it’s “hidden” (unrecognized) , AND, it is a (psychological?) dependency that you don't even notice that you're using. ... [working on an example as a way to further explain] ...

Ivan Reese 2024-08-31 16:22:54

Backing up:

The primary goal of the project is to make a wiki that is nice to read. To that end, there's a build script that adds things like indexes and backlinks, maybe more stuff in the future.

The secondary goal is to make a wiki that is easy enough to write, for now, via GitHub. It doesn't have to be perfect, it's fine if it's a bit clunky. This will probably change — later.

The (distant) third goal is that people can check out the repo locally, and run the build script on their own machine. They might want to see how their writing will be processed without having to loop through GitHub. Or they might want to hack on the stylesheet, or the build script, or add some new dimension to the project that I haven't conceived of.

The (even more distant) fourth goal is to allow people to do stuff from the third goal without needing to run the "canonical" build script. One possibility here is that, if the build script is really simple, people might be able to rewrite the build script in other languages. The original build script would still be canonical — it's the one that GitHub runs, after all — but if a 90% (or 50%) port sufficed for whatever "third goal" thing someone wanted to do, that'd be cool and good and fun.

I have been sharing my thoughts about that distant fourth goal because I find it winsome. There's a Rosetta Code quality to it that makes me wonder a bit. It puts interesting pressure on how I think about the canonical build script, which I've found oddly productive.

What I haven't communicated very well is that I'm still trying to get the primary and secondary goals accomplished, and I'm not ready to get bogged down in considering the fourth goal. I mustn't let myself get distracted by it, because — and I can't stress this enough — the third and fourth goals are not essential to the success of the project.

So by all means, I love that you're playing in the space of that fourth goal. I'd just invite you to treat it as play, and not feel like you need to, say, change my mind about any of it. I don't have a strong sense of what's going on at that level yet, because I'm still trying to achieve the top two goals. Also, when considering that fourth goal, I invite you to think of the build script as a throwaway thing. I'd like there to be a canonical ~social~ understanding of the build script. If we somehow lost all the implementations, we'd just build a new one that did mostly the same thing. If it didn't quite work, we'd tweak it. I have no interest in treating the code or its execution as a source of truth, because the truth is just "do we like reading this wiki?" and that's going to change over time, and it's not a single concrete thing.

Paul Tarvydas 2024-08-28 18:56:37

(by "a bunch of these" I mean 1 for Python, 1 for JS, 1 for WASM, 1 for ???, etc.)

Yuriy Zymlex 2024-08-29 04:17:07

A huge number of languages are compiled into binary code.

Why solutions for binary code optimization didn't become so popular as LLVM and GCC?

Yuriy Zymlex 2024-08-29 04:17:12

The first thing that comes to mind is that each platform requires a different optimizer, but the optimization logic can be shared in some places.

Mariano Guerra 2024-08-29 07:45:10

what do you mean by binary optimization?

most optimizations are done in previous phases in higher level representations like MLIR, SSA etc

Yuriy Zymlex 2024-08-29 09:00:47

I'm interested in a tool common to all languages.

Mariano Guerra 2024-08-29 09:02:08

binary is not common because you can have binaries for different architectures, at that level you lost that context

Mariano Guerra 2024-08-29 09:03:16

the lowest level you can optimize something is at the instruction level for each architecture, which is not common to all targets

Mariano Guerra 2024-08-29 09:04:47

that's why llvm exists, it's a low level instruction representation that can generate instructions for multiple architectures, everyone can contribute optimizations at that level and every language above and every architecture below benefits

Yuriy Zymlex 2024-08-29 09:46:06

This is initially clear. What specifically for x86-64?

Mariano Guerra 2024-08-29 09:47:33

which one, that's a family of processors all with different capabilities and subset of supported instructions 🙂

Yuriy Zymlex 2024-08-29 09:49:51

Right. Although, as I have noticed, optimizers aimed at optimizing intermediate code turn out to be worse for a particular architecture.

Mariano Guerra 2024-08-29 09:50:58

yes, but optimizers for a particular architecture don't work for all the others 😄

Mariano Guerra 2024-08-29 09:51:32

you can solve that with a JIT

Mariano Guerra 2024-08-29 09:52:01

the JIT knows in which particular processor is running and can emit the best instructions for that processor

Alexander Bandukwala 2024-08-29 13:48:38

CPUs also do optimization at the instruction level to some extent. I think the reason that you see optimization happening at higher levels is that the levels are more expressive and easier to reason about abstractly which becomes harder after that information is lost.

Nilesh Trivedi 2024-08-30 08:49:42

I've been thinking about how neurosymbolic AI might be achieved. The first problem is that of memory/knowledge. Triple stores are often recommended. But I am failing to see how triples are THE definitive choice for knowledge representation.

The classic example would be: How to store the fact "Bob's age is 23yrs". This maps to the Entity-Attribute-Value or Subject-Predicate-Object pattern and the triple (Bob, age, 23yrs) works.

But on one hand, even a 2-store can be used:

(Bob, Bob's age)

(Bob's age, 23yrs)

This has more layers of indirections, yes. But the primitives become simpler.

On the other hand, if the fact was "Bob bought this camera in Singapore for 100$", the same layers of indirections show up in triple stores as well.

Arbitrary knowledge seems multidimensional (time, place, context etc etc). Is there a reason to believe that triple stores achieve the best tradeoff between simplicity and expressivity?

Nilesh Trivedi 2024-08-30 09:15:19

The alternative to triplestores that I am considering is Metagraphs as explained here by OpenCOG/Atomspace: github.com/opencog/atomspace/blob/master/opencog/sheaf/docs/ram-cpu.pdf

Mariano Guerra 2024-08-30 09:33:37

is the expert system winter over? 😄

Paul Tarvydas 2024-08-30 12:00:14

I concluded that triples are more practical for what I am concerned with guitarvydas.github.io/2021/03/16/Triples.html

George Campbell 2024-08-30 15:04:00

Replace the text labels with token vectors. 🤔

Guyren Howe 2024-08-30 20:37:20

Triple stores are appealing because you can refer to a well-studied logic (Description Logic). This tells us that triple stores have a very good expressiveness:computational efficiency tradeoff.

Shalabh 2024-08-30 23:13:02

To take your specific example, in a triple store if you add (Jane, age, 25yrs) , it is clear that age represents the same attribute as the age in Bob's triple. It is not clear to me how this equivalence will be represented in the 2-store example.

Nilesh Trivedi 2024-08-31 00:26:15

@Guyren Howe That does explain a lot. Triples naturally map binary relations. "X is R-related to Y" becomes (X, R, Y). It's just that I was expecting higher arity relations (ternary and above) to be as common and important: "X, Y and Z are R-related" would map most easily to the quad (R, X, Y, Z).

The simplest example being sentences describing binary operations : "3 plus 4 is 7".

Kyle Beechly 2024-08-31 02:08:39

I may be naive, but it makes sense to me with analogy to language structure, like Subject Verb Object. There's a lot more you can say that way than with just Subject Verb.

Or maybe it makes more sense as Object Function Result. (Jane, getAge, 25yrs)

Nilesh Trivedi 2024-08-31 02:24:17

@Kyle Beechly The question is: If we want expressiveness, why stop at 3? Why not 4 or 5? For example, support adverbs, adjectives, temporality, context etc natively.

And if we want simplicity, why stop at 3? Why not 2? As in lisp, once a system supports pairs, we can construct linked lists, dictionaries, trees and graphs etc out of pairs quite easily.

Kyle Beechly 2024-08-31 02:53:03

@Nilesh Trivedi Why do linguists only consider Subject, Object, and Verb when composing the constituent order of a clause? I'm by no means an expert here, and don't know offhand what truly separates nouns and verbs from modifiers and adverbials to make this distinction, but there's something here that I resonate with.

As for why three and not two, in analogy to linguistics, how much can we say with only one Noun and a Verb? We can say "Alice hugged," but not "Alice hugged Bob." We can say "Bob was hugged," but how do we convey the relationship between Alice and Bob? I think it can be done, but the complexity of the structure to make that happen might outweigh the complexity of adding the third aspect.

Not claiming to have an answer here, just sharing my raw feels in the hope it might help point to a greater truth

Guyren Howe 2024-08-31 02:53:56

The triple can be considered: relation-column, id, value.

So if you had a table of persons: name, dob, zip code.

Then you can have triples (person-name, id, name); (person-dob, id, dob); (person-zip, id, zip).

This is equivalent to a table where all the non-pk columns are nullable.

Guyren Howe 2024-08-31 02:56:53

If you flip that around, relational purists often prefer a relational model where you can’t store null values, and you just do this sort of thing to represent optional values.

Nilesh Trivedi 2024-08-31 03:04:30

Yeah, triples are perfect for describing standalone objects. But not so much for describing rich relations between the objects.

"X is parent of Y" is fine.

"City1 is 100km far from City2" requires breaking it down into multiple triples, something like:

Distance1 is_from City1

Distance1 is_to City2

Distance1 has_measure 100km
Tom Larkworthy 2024-08-31 07:27:19

triplets, to me, is another representation of a graph. You have the Turing tarpit equivalent issue that everything can be transformed into a graph, so its expressivity is not a problem.

But the question is about *knowledge". Graphs are great for static knowledge (Marid, captiol-of etc.), but real world knowledge often has temporal and spatial element to it. You can kinda tack it on within (graphs can represent anything!) but I think these things need their own 1st class treatment (like the brain does). "Bob lives next" door fact has in implicit today tacked on it, as opposed to objects are subjective to gravity which is nearer universal.

Everything is a timeseries.

Guyren Howe 2024-08-31 16:39:58

Triples give you a pretty good First Order Logic, which Relational Database Theory gives us a really nice way of translating into the Relational Algebra, which is an executable data query language.

I’m not waving my hands all that much when I say that a relational language is mathematically the best possible compromise between expressivity and computability.

Since this is “Future of Coding”, and we are concerned with things like presentation and tooling, we should I think be happy to present triple stores as tables with nullable columns.

That can accomodate your concerns about the dimensionality of the world.

Jamie Brandon 2024-09-01 03:17:16

Does anyone have thoughts about equality vs ordering in maps/sets?

I have some pondering here - scattered-thoughts.net/log/0048/#zest-ordering but the decision tree at the end is the main thing:

  • Order isn't observable at all.
  • Iteration order is either non-deterministic or expensive.
  • Determism can be manually recovered by storing both a map and a list of keys, but at the cost of storing two copies of each key.
  • Order is observable.
  • Order doesn't affect equality.
  • Equality is not extensional ie a == b does not imply that f(a) == f(b) .
  • If [a: 0, b: 1] == [b: 1, a: 0] then we must have struct[a: i64, b: i64] == struct[b: i64, a: i64] , but we still have to remember that the field order is different, which implies that type equality can't rely on interning and pointer comparison.
  • Order affects equality.
  • Sets become surprising / less useful.
  • If I want to add query planning, I can't promise that f(db) == optimize-query(f)(db) .
Jamie Brandon 2024-09-01 03:17:30

Good job collapsing the tree slack 😄

Jamie Brandon 2024-09-01 03:17:51
* Order isn't observable at all.

  * Iteration order is either non-deterministic or expensive.

  * Determism can be manually recovered by storing both a map and a list of keys, but at the cost of storing two copies of each key.

* Order is observable.

  * Order doesn't affect equality.

    * Equality is not extensional ie `a == b` does not imply that `f(a) == f(b)`.

    * If `[a: 0, b: 1] == [b: 1, a: 0]` then we must have `struct[a: i64, b: i64] == struct[b: i64, a: i64]`, but we still have to remember that the field order is different, which implies that type equality can't rely on interning and pointer comparison.

  * Order affects equality.

    * Sets become surprising / less useful.

    * If I want to add query planning, I can't promise that `f(db) == optimize-query(f)(db)`.
Kartik Agaram 2024-09-01 09:32:23

I don't particularly like order being observable by your description.

Have you considered two iterators, akin to Lua's pairs and ipairs?

George Campbell 2024-09-01 17:31:11

What about non-ordered but supporting composite keys where one of the components is the order?

Jonathan Edwards 2024-09-01 20:43:14

It’s so refreshing to read a discussion of design tradeoffs rather than being presented with a post hoc rationalization. Your discussions heavily weigh performance, so it would make sense to avoid ordering and allow non-determinism. I favor order for user-friendliness. Translating into your terminology, I provide sets as maps to a unit value that are auto-sorted by key value.

Shalabh 2024-09-02 02:11:45

Do you see ordered objects as being mostly useful for users? Or mostly incidental and only occasionally useful? In general I prefer key/value bundles to be unordered. I can still add order by encoding another list on the side as you mention. It also seems easier to evolve the language from unordered to ordered iteration if needed, than to go in the other direction.