lately i’ve been playing with prolog and revisiting computer science/computer programming before imperative languages drew a curtain on innovation and i think we have lost a lot. our modern programming isn’t the programming the founders had in mind, it seems.
But imperative ones create a bit of a problem. Nothing impossible to deal with, but it becomes harder.
But any choice of language, the OS can enforce it too, and maybe in a much easier way than messing with your language.
Designers will put much more thought into how best to interact with a framework, so start with a small, opinionated interface then consider extension feature requests on a case by case basis
I think some functional programming languages solve that by running a good chunk (if not all) of the application in a single trace.
And, of course, async/non-blocking calls, as tracing a call along different threads or promises may not be available all the time.
Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened."""
For example in php class A { public $a = new B;} is not valid
Such a restriction makes no sense in a "closures are a poor man's object" world.
I think there is still hope on that front. Following structured concurrency patterns like the supervisor model should handle it. See the discussion about "Notes on structured concurrency, or: Go statement considered harmful" [1].
it's certainly not a given
No different from an object that got constructed and then a method called on it.
i thought you meant state that is created from a call stack and persists after that call stack returns -- which is something else
It's mostly feasible in other languages to, but probably not with the same level of rigor.
Anybody here from JetBrains?
Am I the only one that thinks pull requests (asynchronous) are a more appropriate medium of collaboration for this kind of work that requires strong consistency between elements?
This kind of reminds me of the Whyline: https://www.cs.cmu.edu/~NatProg/whyline.html
Yippee. /s
Isn't that just a debugger?
> spack -e default config blame packages
--- packages:
spack/environments/default/spack.yaml:59 fftw:
spack/environments/default/spack.yaml:60 require: ~mpi
spack/etc/spack/defaults/darwin/packages.yaml:17 all:
spack/defaults/packages.yaml:18 compiler: [apple-clang, gcc, clang]
spack/defaults/darwin/packages.yaml:20 providers:
spack/defaults/darwin/packages.yaml:21 unwind: [apple-libunwind]
spack/defaults/packages.yaml:20. blas: [openblas, amdblis]
spack/defaults/packages.yaml:21 jpeg: [libjpeg-turbo, libjpeg]
spack/defaults/packages.yaml:22 lapack: [openblas, amdlibflame]
spack/defaults/packages.yaml:23. mpi: [openmpi, mpich]
spack/defaults/darwin/packages.yaml:22 apple-libunwind:
spack/defaults/darwin/packages.yaml:23 buildable: False
spack/defaults/darwin/packages.yaml:24 externals:
spack/defaults/darwin/packages.yaml:27 - spec: [email protected]
spack/defaults/darwin/packages.yaml:28 prefix: /usr
The filenames are shown in color in the UI; you can see what it really looks like here: https://imgur.com/uqeiBb5For the curious, there is more on scopes and merging [2]. This isn't exactly easy to do -- we use ruamel.yaml [3], but had to add our own finer-grained source attribution to get this level of detail. There are also tricky things to deal with to maintain provenance on plain old Python dict/str/list/etc. objects [4,5].
[1] https://github/spack/spack
[2] https://spack.readthedocs.io/en/latest/configuration.html
[3] https://yaml.readthedocs.io/en/latest/
[4] https://github.com/spack/spack/blob/95ca9de/lib/spack/spack/...
[5] https://github.com/spack/spack/blob/95ca9de/lib/spack/spack/...
However, there is still a lot of room for improvement in compilers and debuggers. If I could tell the compiler to instrument my code to track the values that I care about, and then have the debugger visualize the flow of information through the system, that would be very useful. It wouldn't guarantee that the data flow analysis applies to subsequent runs of the program, but it could reduce the amount of time spent reading and debugging code.
I think there is a new era yet to come.
> probably too complex to visualize in a usable way
You can always abstract the complexity. A simplification of the control flow graph at the function level.
As an example, I want to understand the Postgres codebase better...there are a lot of very visualizable things going on there. If you look at lecture slides on relational DBMS, there are lots of diagrams...so why can't be view those animating diagrams as the code executes.
I was thinking of instrumenting the code to get a trace of every function call and its arguments, and then filter that and visualize it.
The key to this approach working though is a think ultimately we need to write our code and organize our code such that it can be easily visualizable. The purpose of code is for humans to understand it, otherwise we are writing assembly.
Static-checking tools and strongly-typed languages: "Are we a joke to you?"
Finding and removing bugs before the code runs is still debugging.
Man, you would love functional programming. I'm' not even joking.
Microsoft IntelliTest (formerly Pex) [1] is internally using Z3 constraint solver that traces program data and control flow graph well enough to be able to generate desired values to reach given statement of code. It can even run the program to figure out runtime values. Hence the technique is called Dynamic Symbolic Execution [3]. We have technology for this, just not yet applied correctly.
I would also like to be able to point at any function in my IDE and ask it:
- "Can you show me the usual runtime input/output pairs for this function?"
- "Can you show me the preconditions and postconditions this function obeys?"
There is plenty of research prototypes doing it (Whyline [4], Daikon [5], ...) but sadly, not a tool usable for the daily grind.
[1] https://learn.microsoft.com/en-us/visualstudio/test/intellit...
[2] https://link.springer.com/chapter/10.1007/978-3-642-38916-0_...
[3] https://queue.acm.org/detail.cfm?id=2094081
In my experience most actuaries I interact with maintain truly horrendous spreadsheets with labyrinthine complexity.
The distributed aspect is a bit more difficult though. I don't know if there is a system that truly got this right. Maybe Erlang's BEAM VM together with a good debugger I don't yet know about.
Sweeping generalizations rarely age well.
> You can think of everything as configuration. Parameters of a function are just configuration for that function.
No, parameters of a function are contextual collaborators which participate in a function implementation. Configuration canonically influences a program aside from its individual run-time interactions.
Is a value given to the cosine function a configuration? Words matter.
> Every task in software is wanting to change what is displayed in a user interface of some sort.
This is a myopic perspective. Software processes data into information which provides value in context. This may never be "displayed in a user interface."
To wit, the network gear involved in my posting this reply most certainly qualifies as a "task in software." So, too, is the software running in the power companies involved. It would be quite a stretch to categorize them as "wanting to change what is displayed in a user interface."
You can think of everything as configuration. Parameters of a function are just configuration for that function.
What we need is traceability of every value in a system, not just configuration. You click on any value and you see a graph/chain of all the transformations this data goes through right back to the source of truth. This is how we should code. Think about how difficult this is to do today with your current IDE/editor.
Every task in software is wanting to change what is displayed in a user interface of some sort. Usually you have to make your way through a labyrinth to figure out what to change where, and also what side-effects will occur.
If this is not smack bang in front of your face when you are coding, then you are just adding more and more tangled data flows and complexity to your system.