Value-Oriented Programming
accu.org
accu.org
I read a whitepaper on value semantics: https://arxiv.org/pdf/2106.12678.pdf
I think it's promising.
I've been working on multithreaded code that passes references around. If you hold the reference, you have exclusive access for reading and writing the data at the reference. In theory you should only send values between threads when you need to pass exclusive access to a thread. At all other times, data is completely sharded between threads. The only reason to pass a reference around is to pass data between threads, similar to a queue but not quite. I deliberately avoid updating shared data structure such as a list that both threads are processing. Instead, each thread gets a shard.
I get 6,359,793 requests per second of passing reference around with this approach. Ideally each reference should correspond to a large amount of CPU work (at least 1 second), so that you shouldn't need to pass around references between threads that fast. This is 150 nanoseconds for a synchronization event, roughly 1.5 memory accesses.
But still, I think that the proposed solution is at the wrong level. I think it would be much better to talk about the specification versus the implementation level. Instead of saying this function works correctly when certain pre-conditions are met, you could also say that a function implements a function under for a certain value domain. The article, the function 'floorSqrt' could be viewed as a function, which implements the generic floor of square root function, for a certain value domain, namely positive 'int' values. (You wonder whether the input type was not of 'unsigned int'.) It is not even clear from the context, what is the maximum value of 'int'. That the result is always valid for the input values is clear.
I think that for the development of software engineering, it would be better to focus less on 'programming' languages and more on 'implementation' languages, languages that specify how a generic (often matchematical) problem, can be implemented in a programming language. Instead of developing yet another programming language.
Anyway I thought it was sort of ironic that the idea is this good because it does the thing everyone tells you not to do (hashmap all the things), but now that someone has written a book on it you have at least the air of respectability.
[1] https://www.youtube.com/watch?v=Vz9rkr_p3Ts [2] https://www.manning.com/books/data-oriented-programming
That said, I very much believe in the value of values. Data should have no associated behavior or have a "place" in memory, the place and the behaviour are secondary. That's why, ironically, "Manager" objects are the best type of object you can have, contrary to OO best practice, because they don't own the data, they just provide a place and behaviour for a particular usage.
The idea of "everything is a hash-map" is also possible in statically typed languages to some extent using row-polymorphic structural types. OCaml and Elm or Koka are great examples.
Yes! I've been playing with this recently. For context, long term, I'd like a pushout lattice of theories (types, operators, laws) to get math-like locality. But for a more near-term puzzle, what might highly expressive metaprogramming and collaborative compilation look like?
There are lots of papers on say "tweak some language to add a bit more control over memory layout"... but what if you want subsume all such, concisely. To permit much more gracefully moving around implementation design space. So you can flexibly and concisely express and mixin domain "asks" - this range of values, that variant of `mod`, this handling of alu flags, "try it exact, now bounded exact, now floatNN, now run UW's Herbie to optimize float expressions", with what radix and offsets and scaling, with what intermediates, with what bits landing where manged by whom, etc. Etc - that was merely numbers. With sort of Maude-like[1] "in this scope I want imported these operators and semantics", but more composably over a higher-dimensional design space.
Apropos a sibling comment, I'm currently at compile/collaboration-time "hashmap all the things", tied in with scoping. Eg, it's not just a literal "5" ast node, it's a rich set of collaboratively and lexically expressed and inferred constraints and preferences over implementations. (If anyone knows of a rich hashmap/assoc/dict combinator library, I'd appreciate hearing of it.)
[1] err, not a great sample but: https://maude.lcc.uma.es/maude321-manual-html/maude-manualch...
I’m working on a language that will be sort of a cleaner TypeScript, more simple and sound, with powerful static types, but not ML.
I think functions taking not just read-only views of data structures but deeply “const,” unchanging views is really important. Code that runs in GCed runtimes like JS engines or the JVM can be quite performant, but not with the level of copying and allocation that immutable data structures typically require (when you need to model them changing over time), and I want to solve that at the type level.
I do think however that (safe) Rust can be said to have mutable value semantics, if you forget what a borrow “is” you find yourself exactly with a value-oriented language.
And I think it's a wonderful way to code once you wrap your head around it and unlearn Java.
The best experience that i've used is Haskell, where there's no "goto".
Structured programming is fine, but almost no languages except python support the while...else construct.
The semantics are to execute a loop body while the condition is true, and then to execute the else body when it isn't. But if you break out of the while loop, the else is not executed.
It does not always hurt to use goto to implement the correct control flow when required.Arguably, the code is clearer as well.
EDIT: I'd prefer to actually have a while else construct though!