Is there a specific topic, concept, etc.. that no matter how many times you try to wrap your head around, you can't ever seem to get it? If you were in this situation, what would you do?
This is my take on it: when you start something it's at first easy and then it gets really hard. Or boring. Or you get distracted or disenchanted. But if you stick with it long enough you eventually become an expert in the space (or what you are building becomes good enough) that it's not state of the art. And then you can innovate on it or sell it or sell your skills. But you have to get through that tough valley in the middle.
Atomic theory after about 1960. I had no trouble at all getting down to photons, neutrons, electrons, protons, etc and how both fission and fusion works. But when it came to quarks, mesons and spin, I could never work it out to my satisfaction.
I think to get some sort of understanding (instead of just operative understanding of quantum mechanics) you have to dive relatively deep into theoretical physics.
Spin can then arise from enhancing the Schrödinger equation with a relativistic description of mass and impulse [0].
call/cc in Scheme. I’ve tried a few times to understand it (and I kind of do on a certain level), but still don’t get how to actually use it effectively in my code
I feel that I sort of get it - after listening to many many podcasts by scientists trying to make it understandable. It took me years. And still I may be wrong, so please consider what follows as an essay.
My first major step was to really understand that gravity is a law and not a force.
This is totally counterintuitive since we feel gravity as if it were a force, and because many people use the expression "force of gravity".
So a mass should be viewed as a "tag" that an object has - and the higher the number on the tag, the higher it deforms the space-time around it.
My second major step was to understand that all objects, for example planets, always go straight along a line. They appear to have an orbit because they move in a space-time that is deformed by other planets and mainly stars or black holes.
The moon goes along a straight line in its space-time. But the latter is deformed by the mass of Earth so it looks to us living in Earth's space-time that the moon is orbiting around Earth.
The third major step is to understand that the two space-times mentioned (the Moon's and Earth's) are not "related". Someone on the moon lives in a different space-time than someone on Earth.
So the duration of time that person lives on the Moon as measured by an atomic clock he/she brought will diverge with an atomic clock on Earth.
The difference won't be huge, in truce very very small - but measurable.
Everyone of us lives in its own space-time. Because the gravity is not equal on the point of Earth surface. Because of mountains, and because the Earth itself is not homogeneous, and because we move around and up and down all the time.
In final, this means to get rid of two related notions that appear so self-evident that it is almost impossible to really get over with:
- there is a common 3D space that we all share ;
- there is such a thing called time that is totally independent and flows continuously.
What really exists - for each person or object or planet - is its own space-time.
And all these space-times are unrelated to each other.
The proof of it is that there is a maximum speed limit to any existing thing. That maximum speed does not vary whatever are the speeds of two considered space-times.
The only thing we know that reach that maximum speed happens to be the light in space.
If the two space-times were related, then the speed of light would vary if one space-time is moving in a different direction and/or speed relatively to the second considered space-time.
But it doesn't. So you and me don't share the same space-time. So, between two encounters, we won't have lived exactly the same duration of time. Our personal atomic clock, if synchronized at the first meeting will have diverged when we meet again.
Of course, the difference will be so super small that it's unnoticeable to us (but measurable with today's technology).
GPS satellites orbite at around 36,000 kms from Earth. That's far enough to make GPS calculations quite wrong if Einsten's relativity is not taken into account (by around 50 meters). That is noticeable.
By the way, Einstein deeply regretted his poor choice of words. Because its theories of "relativity" precisely demonstrate that the different space-times are NOT related.
We need to understand that space and time don't exist. Only unrelated space-times co-exist, within which time as we feel it flows at a different pace than in other space-times.
But there is only one "Reality", right? Well... that really depends what we mean by that. The only common point among space-times is the respect of causality.
That sort of reinstates time as we feel it. If A causes B, then B can not precede A.
In a sense, events creates time as we know it. After all, we are all very often surprised by the time it is on our watch. So this "unstoppable Time that flows no matter what" that we think as self-evident in our representations ... just doesn'...
Fascinating essay, thanks for putting all of that down.
You have thought about this plenty. The only thing I'll add is that all objects live in the same spacetime. The metric of that spacetime is a mathematical object that obeys known laws under coordinate transformations, and the parameters of those transformations depends on the energy momentum tensor (likewise an object that transforms...).
Trouble with GR is that the "trivial" solutions are heavy shit. So it goes.
Teaching anything when the student doesn't want to learn is a bit futile. I was taught physics at school. I am actually interested in physics now, and I am finding the historical progression, the story behind the move from an older model to a newer one to be very enlightening. I was taught this way at school but I just didn't understand it and wasn't interested enough to pay full attention. I think there is value in telling the historical story of physics, just only to interested students.
Yes! That's fascinating and thank you for writing that. It expanded my knowledge. You should put that in some sort of linkable format.
However, think about insane it sounds.
Like if we didn't have the subject physics or if you had to explain it to a medieval king in the 1300's.
They would think we are totally insane.
Because it is different than what our everyday hairless monkey lizard brain sensory organs are reporting to our brains.
That's why I struggle with it.
Cool example of satellites. That actually grounds it in an understandable example.
Also does relativity discount Newton?
Or can it be viewed as an extension?
> Physics is like History. We keep on learning at school things that we know to be at best approximate and very often just plain oversimplification that leads to misrepresentations that are super difficult to correct.
I think all of science is like that. It's continually advancing and changing our views of the universe which is beautiful.
Im going to tell my boss next time I'm late that I'm not late it's just that our space times are subjective and aren't currently synchronized.
Have you ever read the chapter on Decorators from Design Patterns? I’d recommend that for a full treatment, but basically it’s just a way of letting you add on additional work for a function call to do. If we had a decorator called @log(), and a function add_two, if we added this decorator on to add_two it will log the function call or some other aspect(as we define it.)
Wow thanks im gonna read that today!
That explanation makes quite a bit of sense. Ive been reading over some code to try understand what it does and now its starting to make more sense.
A lot of things can be conceptualized as an operation that takes some stuff, and gives back some new stuff, and does absolutely nothing else.
It's like a lot of other strong constraints on complex endeavors. If you run with it you can get surprisingly far, but only by twisting your understanding of how to do things. Whether that's good or not seems highly personal though.
This is a great explanation. As someone who's a relatively recent convert to FP and am currently writing both imperative and functional code I will test my own depth of knowledge by trying to explain it
1. In traditional (imperative) languages you can have functions that deliberately or accidentally either modify the data they were given or do some other stuff that changes data somewhere else in your program or the computer.
Let's take an example of each. Say you have a function that adds two numbers a and b. In imperative languages you could return a+b into b. In other words the sum(a,b) operation would change b. That's not cool in FP: you are (almost never) allowed to change the input you received. This way whenever the function is called with a and b it always returns the sum (otherwise if you call sum(a,b) again you will pass in a modified b).
This makes every function guaranteed to always return the same value for the same arguments. If you accidentally try to change a parameter in your code it will fail.
But you still need to make changes to the world - you do so by chaining these functions and using the output from one as input to the next and so on.
Last but not least, functions that have side effects (e.g. print to the screen) are marked differently and usually their effect is isolated.
A way I heard it explained that made it make sense to me is this:
FP is basically making all of your inputs and outputs explicit. In OOP if you have some bool on a class that affects what a method does, that private bool is technically an extra parameter for that method, even if it doesn't get passed in. Similarly if a method changes some integer on its parent class, in a sense that integer is technically part of what gets returned by the method.
Functional programming forces you to actively think about all of the extra inputs and outputs of your code. In turn, this helps you avoid unintended side effects from the internal workings of a method etc. and the bugs that they can cause.
While the ideas behind FP are useful and can help you think about your coding in a cleaner way, I also think they can be overdone and taken to almost religious extremes. And it can come with a cost of worse performance, more difficult to write/maintain code, etc. , though done right it can have the opposite effect. Done right, it can also make certain aspects of asynchronous and parallel programming easier to work with.
FP, OOP, and all of the other programming paradigms have useful concepts, but purism for any paradigm can lead to all kinds of problems. The obsession with "state" that you see from some FP evangelists is especially annoying, because it ignores that in almost any useful program there will be an irreducible amount of state that has to be tracked and dealt with.
You are essentially working with functions that receive input and return output, and are not allowed to change anything outside them.
The simplicity is in that you create multiple levels of abstractions by only combining functions: low-level functions do some "dirty" work that the program needs to perform (slice cucumber, open oil, pour oil, add salt, etc); you then combine a couple of such low-level functions in another set of functions - making it a bit more abstract (make salad, prepare table); then you combine these abstract functions into even more abstract ones(prepare dinner), etc.
There will be also some "helper" abstract functions that can be reused in different contexts (slice something, open something, put some food on the table, etc).
Because each function - no matter the level of abstraction - only takes input and produces output - it's very simple to write, read, reason about, and test.
Obvious question you might have right now: how can you write a useful program if you can't change anything outside the function or interact with the outside world? Well, that's the "dirty" part of writing a FP program. You just write your program trying to keep it as "pure" as possible, pushing the "dirty" parts away as much as possible. Think Layered Architecture but for programs. You keep the "outer layers" of your program "dirty" - reading/writing to the DB, making network calls, etc - and preserve the "purity" of as many "inner layers" as possible. For example, when you want to write to a DB in one of "inner layers" which should stay "pure" - you can return your "desire to write to a DB" as a string(or however you encode it) to your outer layers, which will then perform the actual operation by actually talking to the DB. The inner function stays pure because it doesn't actually talk to the DB, it only returns instructions for outer layers to talk to the DB.
Depending on the language you are using it might be either beautiful and easy, or extremely awkward and overly complicated. Most of the time it's something in between.
Still don't have even the vaguest beginnings of a clue what the fuck a monad is, after reading 50 articles promising to make it simple, as well as their accompanying 500-comment HN threads. I suspect the real problem is that, as a C/C++/C#/ASM programmer, I lack concepts that are strict prerequisites, and people underestimate the importance and/or existence of those prerequisites.
What I did was I gave up and no longer click those articles.
This is very relatable :) A workmate and I have fun making variations of "A monad is just a monoid in the category of endofunctors!" and sarcastically suggest the other tries OCaml, Haskell, or Idris when something isn't going their way.
I've been pretty deep in to functional programming for years including implementing my own little lisp with macros and all that shit and I still couldn't confidently tell you what a monad is. I read those articles sometimes when I come across them and feel like I understand a little more of... something... and I mean I have some intuition for what they are but still I don't really get it and never have.
When you have some spare time write a function that returns a Maybe<Value, Error> and see what a pain it is to compose multiple of them.
Then, try store your programs state by passing it as a function argument to every function so it stays available for the lifetime of the program (no mutable state? This is basically what happens)
After realizing what a pain this is and wishing for boilerplate, look at the State monad. This is what did it for me :)
I don't see why I would ever want to do the first one in real life, when exceptions exist.
I'm honestly not even sure what function composition is, or why you would compose two functions instead of just explicitly making a new function that calls the two original ones.
The second one makes more sense because of the rumored bug-freeness of side effect free apps, but it seems like for that too, you'd need to understand a lot more than just monads.
Function composition is connecting the output of one function to the input of another. In math it is (f ∘ g)(x) = f(g(x))
Or in javascript:
function f(x) { return x + 1 }
function g(x) { return x + 2 }
f(g(1)) === 4
In functional languages like Haskell function composition is made easy, because functions can be partially applied. Partial application means that given a function that takes two arguments, I can call it with one argument and it will return a function that takes one argument which returns the result. Whereas in languages like javascript it is difficult because functions can have different numbers of arguments and there's no way to partially apply them or flip their arguments, so it is difficult to chain functions together. And because javascript functions aren't pure, they may not have any result which can be composed with other functions. In a functional language, functions are more like the functions in math. In most non-functional languages, functions are more like a procedure of commands. For example, the javascript function logMe(x) { console.log(x) } doesn't return anything. So it can't be composed functionally, and is not like a "real" function.
JavaScript has bind() on functions which works well enough. You can partially apply arguments, but I don't think you can project them to a different order.
JavaScript has closures. When you want to partially apply something(Which is technically never, because we would probably describe it in different words and think of it differently) we just make a new function.
When we want to "compose" two functions, there's f(x){return a(b(x))}.
It doesn't matter if the signatures are different, you don't need any nice logical idea of composition, you just explicitly build the new function that does what you want.
I would say that is a lot easier than real composition, because real composition requires you first learn to see and think in terms of patterns you would want to compose in the first place.
Also, function chaining doesn't use intermediate variables. Named variables are like free documentation. With composition you have to actually remember what you're doing. Making everything explicit makes it easier to comment what's happening.
Regular programming is to math as cooking is to chemistry. Functional brings the math back to programming. Math is useful but also hard.
In OOP, more often you're doing the equivalent of:
if crinkle(a(b(x,68), modes.FOO).bar.baz(9)):
x = foo()
else:
x = wipe(7).bar()
And I think it's a lot nicer to just spell it out with meaningful variable names, instead of trying to compose it like an equation.
Not every step has a meaningful name. And usually you already have the name of the function. For example:
let batter = mix(water, flour)
let saltedBatter = add(salt, batter)
let risenSaltedBatter = letToRise(saltedBatter)
let bread = bake(batter)
on the other hand:
let bread = bake(letToRise(add(salt, mix(water, flour)))
The first example leads to awkward names and useless variables. The second example feels cleaner to me. Interesting that you take cooking as an example: recipes usually don't name most of the intermediate steps, they describe the actions you take and the ingredients you use. Most recipes also use composition a lot. You start with your actions/functions (cut, cook, bake, dice, etc) and you do a recipe out of them. You don't create new "functions" (actions) specifically for each recipe.
Recipes are a lot closer to configuration DSLs than code though.
You have standard functions like bake and boil, and they don't tell you to use clean utensils or how to turn the stove on, because an cooking is basically just a few dozen standard functions, end condition rules, etc.
If you think of them as programs, the composition they use isn't the same as functional languages, because the individual steps are unstructured and there's no generalized abstract pattern defining what a RecipeStep is or what composing two of them means.
You wouldn't say add(flour(add(salt,empty))), you would say "add flour, salt, water, and yeast".
"add" can take either an ingredient or a list, and it's pretty encapsulated, since it dynamically selects a way to measure the ingredient based on what it is, what utensils you have, etc.
It could trigger dozens of unrelated code paths based on state, and probably includes error recovery.
Functional might be nice for implementing the internals of that add() function, but in OOP the idea seems to be that it's a pretty minor detail, since add() is only written once and rarely changed, but used millions and millions of times all over the world for a decade.
Usually when people talk about "the beauty of functional" I get the impression that they're not really doing a whole lot of "One really smart function that knows exactly what to do" level abstraction.
It seems like they'd literally be composing together their own variations of what "add" is, as needed from the raw findMeasuringStrategy and checkPantry functions instead.
I feel, in your example, that the first code block is infinitely more useful to the maintainer than the second. It literally tells the reader what each step is *supposed* to do.
That second example tells the reader that it is doing, which may or may not be what it was supposed to be doing.
As a maintainer, I prefer knowing that:
(add(salt, mix(water, flour))
is supposed to result in a salted batter, which the first code block tells me but the second one does not.
My whole point is that sometimes intermediate steps don't have good names. I often have to apply multiple transformations to a collection, but only the first and last step have a name because the intermediate steps are just that. "salted batter" is not a thing, it's just a placeholder name because you needed a name. You will never use "salted batter", you'll only use ingredients and bread.
> You will never use "salted batter", you'll only use ingredients and bread.
For write-only code, sure, that's great.
It's irrelevant when I am tracking down a bug - the label 'saltedBatter' tells me what that intermediate result is supposed to be.
If, when debugging, I find that `add(salt, batter)` results in something else[1], using your convention it is literally impossible to tell that the value is supposed to be `saltedBatter`.
There is literally no way to tell if the intermediate values are correct. Maybe each caller in the composition chain can throw an Exception?
The point is, the variable names are helpful.
> but only the first and last step have a name because the intermediate steps are just that.
That describes the entire program :-)
In all seriousness though, it's because you intend to describe steps in the process that throwing away all labels for the intermediate steps makes sense.
You're describing verbs. We don't need to know the in-between verbs for a verb. When you call `driveTo()`, it is not necessary to know all the verbs involved in that action, it is enough to know that it will attempt a certain action.
Verbs answers the "what we are doing" questions.
Variable names answer the "Why we are doing it" questions - `saltedBatter = foo (bar(), baz);` tells the reader why foo is being called.
We don't even need to know the steps involved or even what the other variables (used as parameters) should be. Assigning the result of a function to a variable ensures that the maintainer knows if that variable ever holds the wrong value.
I think where a lot of this value (variable-names) is lost is in enterprise development - the names are never helpful, they're just a differently-cased version of the type. Like these gems I see daily:
you, as the maintainer, know exactly what that last line is supposed to do, and if it isn't doing that, then you know it's a bug.
Compare with this:
return (foo(), bar());
Or, if you wanted descriptive function names:
return (calculateResult(), userSubmittedList());
Brevity is not a virtue in programming languages and/or programs. It's probably why Haskell is still not even a rounding error as far as popularity goes.
[1] Maybe `doubleSaltedBatter`, in case an upstack caller used `saltedWater` in place of `water`, or perhaps `pepperedBatter` in case a caller switched out the salt for pepper.
A function that can return a value or throw an exception is pretty similar to Maybe<value,error>
I'm not clear why the next function in the pipeline would need to know about the error rather than the caller, but that happens with promise chains too
Maybe this article will explain my point about errors a little, it also covers function composition, and I think is approachable. I guess the only advice I have for you (or anyone) with monads is to look at concrete examples first and not care about the theoretical bits. Intuition comes from use. Is it useful to know in non-functional languages? Probably not; you'll use them without realising and probably make them yourself without realising!
I remember one time I found an article that explained it. For a brief moment I thought i understood. But I didn't see what was in any way interesting about them, so that probably requires a whole other level of knowledge.
All I know is they contain values and you can pass them functions, and somehow by doing this you can write fully pure programs with supposedly fewer bugs, and Haskell programmers seem to not understand why this is hard.
One thing that made it difficult to me was that I didn't explicitly realize for a long time that there were two things to understand: what a monad is and why they are useful. Most explanations tell why it's useful, but it really clicked for me when I read through the book "Haskell Programming from First Principles" (Julie Moronuki, Christoph Allen) [1] and got to the monad chapter, which if you read the previous chapters explains really clearly what a monad is.
The way I understand monads: some data structure plus 2 functions, "return" and "join":
- "return": wraps something with the data structure. (no relation with the return keyword you are used to in most languages)
- "join": joins 2 layers of the _same_ data structures into one.
And that's it. It's just that simple what a monad is: in java it would be an interface with just these two methods.
Examples:
- "return" for List: takes a value and returns a List containing just that value.
- "return" for Maybe: takes a value and returns Maybe value.
- "join" for List: takes a List of Lists and returns a flattened List (2 outer layers joined).
- "join" for Maybe: takes Maybe Maybe value and returns Maybe value.
I think what makes these functional programming concepts hard to grasp most of the times is that communicating the boundaries of abstract concepts is hard in general, even if the concept itself is really simple, like a monad can be for a programmer.
As for why monads are useful, the explanations you can find online give a lot of examples. Just think of all the times you may have used flatmap for arrays: that's just map followed by the "join" for arrays, which is sometimes called flatten. The other operators you see used in haskell, like "bind" (>>=), can be derived from "join" and vice versa and are just conveniences to write code with less noise, like flatmap is.
Recap: monad is the name of the concept for things that have a "join" and a "return" functions defined. Basically "join" is the distilled concept of what a monad is.
It explicitly tries to answer the question: "I’m a C# programmer with no “functional programming” background whatsoever. What is this “monad” thing I keep hearing about, and what use is it to me?"
> Still don't have even the vaguest beginnings of a clue what the fuck a monad is, after reading 50 articles promising to make it simple, as well as their accompanying 500-comment HN threads.
I have an article i'm about to publish that will have a lot more real world examples... hopefully it can bridge the gap.
It'll also have exercises, which are honestly the most important part of understanding.
I’m a self-taught programmer, so have probably missed lots that might help, but every time I come across anything OO, it always seems unnecessarily complicated and awkwardly structured. It always seems (to me) that everything could be done more simply procedurally. I don’t get why.
Further, while I can follow OO code that others have written, as a beginner, how to structure something simple I’m writing de novo in an OOP style has a very steep learning curve.
Dear ImGUI keeps a bunch of state under the hood, based on the name of the object. It's not object-oriented, per se, but each object has its set of functions that operate on it, except that the object reference is not a pointer but a string. Kind of like object-oriented C (NOT Objective-C), but with strings instead of pointers.
FWIW, after I learned/memorized the semantics of C++, it did take me at least 3 years of writing lousy code to develop a sense of how to structure a program, e.g. what ‘should’ be a class, when inheritance is appropriate, etc. As for the why, I find it a useful formalism for how to organize (as in, group and associate) code and data, as well as a way to create mental-cycle-freeing guarantees (invariants).
In my opinion one of the weaknesses of OOP is just how hard it is to actually model those real world relationships in any concrete form. It's choosing to professionally have a fight with "the map is not the terrain."
Some people are really good it but it's a skill for sure and learning it is rough. It is some really abstract thinking shit, and difficult even to evaluate how well it has been done until much time has passed with it.
I think when people joke about naming in programming this is what they mean. Needing to clearly define relations that are not necessarily clear yet. OOP does demand a lot of that so is hard and exhausting in a particular way.
That said nothing against OOP I use it every day and Sandi Metz is the code book writer I learned the most useful stuff from. Just it's hard in a different way from most of the rest of coding.
Absolutely. I'm continually amazed as how much and how hard people have tried to push everything into their OO framework.
Android development is the classic example - it's ALL OO - and most of the time, that's pushing the proverbial uphill. Instead of just initialise something, everything is pushed into constructors. The model works sometimes, but for many things it just adds work. AND ADDS ENORMOUS AMOUNTS OF BOILERPLATE. Aarrgghhh.
Take a weekend to learn Smalltalk, then it will all make sense. Objects composed of other objects, all passing messages to each other. Whether you can then take that knowledge and have it make sense in a Java, a Python, a C++, etc is hard to say...
Someone will probably chime in with Smalltalk and the original intent or something.
But in modern OOP, understanding and simplicity are not what it's all about.
It's all about pushing the complexity into the language runtime stuff where it is no longer your problem.
OOP is popular because we can do stuff like port=DBConnection(); port.connect("foo.baz") and document= port.request("x").
Then, later on, when port and document are inaccessible, garbage collection will get them.
An OOP programmer doesn't think "Oh, the port.connect must make a socket and do a handshake and then..." they just think "It does all the port connect stuff".
As a student when the goal is to understand, OOP makes no sense, because encapsulation literally is all about making it so you don't need to think about things.
It lets you treat objects the same way we treat physical devices. Black boxes someone else built.
There's no beautiful reasoning or amazing objective logic saying OOP is better than I know of, or anything that even makes any sense at all if you think about it.
It just happens to work pretty well when people with a wide range of skill levels do large projects and nobody understands anything beyond their tiny part, and nobody really cares if things are simple under the hood.
If you want beauty and logic, learn a pure functional language or go study math.
And if you want to structure stuff in an modern OOP style, you just stop thinking in terms of simplicity and unified wholes and start thinking in terms of black boxes to be used by people who would be annoyed if they actually had to read the code.
Any entity you would talk about when describing the code is something that could be represented as an object.
Any collection of a variable number of a ton of entities like customers is something you could do as some kind of database connection object.
Any periodic task might be a "Machine" that is a class that manages a thread.
It's(In theory) a 1 to 1 mapping of ideas to classes, although some things just aren't worth a whole inventing object for and should probably be a data dict+procedural.
But, some would say this whole thing is nonsense for idiots who can't think, so maybe if you find yourself actually able to do procedural well you should try something more logical like haskell.
The only difference is that you can stop doX(data, args) from modifying parts of data. However you can do the exact same thing in non-OO languages like C or Haskell by using void* (in C) or (in Haskell) modules with hidden constructors.
The only true OO language out there is Erlang. C++/Java/C# etc. are not OO languages.
The idea that OO is modelling the world is BS. You don't ask your shoe to tie itself or ask a tree to chop itself.
And you don't ask an integer to display itself in a dialog in an "OO" language unless you are a bad software designer.
IMO OOP is simply procedural programming with structs. Except, that whole "struct thing" is much more elaborate and fleshed out and has a much more emphasized philosophy behind it.
- How type theory can prove mathematical theorems. I can limp through the first exercises of Software Foundations, but eventually realize I'm just "making it work" instead of knowing how it works. Only made it halfway through My Little Typer and even implemented STLC and used it to prove simple propositions with implications. But I still couldn't tell you how dependent types magically make it possible to prove real theorems.
- How opamps work and how they're used to make a differentiator.
- How quantum computing works. I want understand it to understand why factoring and discrete log fall to QC but not the post-quantum algorithms. I never make it past the intro chapters.
- What exactly makes cryptographic hash functions have desirable properties like collision resistance? Bits go in, bits go out, why can't full observation of the process not yield a method to construct inputs for a target output? Similar questions for block ciphers. It is much easier to "see" the impossibility in public key schemes because you can play and experiment with the math. In symmetric algorithms it looks like just a bunch of arbitrary bit operations.
EDIT:
- Relativity. I accept things like time dialation and nothing can go faster than the speed of light. But I have no idea why you would experience less time passing than me after a high speed rocket trip when, from your perspective, you saw me on a high speed planet trip. Or what prevents a rocket in space with 3m/s^2 acceleration from reaching the speed of light after 100,000,000 seconds.
>How opamps work and how they're used to make a differentiator.
An op-amp is just a very high gain amplifier. It senses the difference in signal levels and just amplifies that difference by a large amount, usually between 1000 and 10,000,000 times.
The first op-amp circuit you usually use is a negative feedback linear amplifier. In this circuit, the positive input to the op-amp is simply grounded. The input voltage is put through a resistor R1 into the negative (AKA inverting) input. The resistor limits the current into the negative input to Vin/R. As soon as the voltage on the input becomes non-zero, the output of the op amp becomes a quite large signal, of the opposite sign. If you feed a small amount of that signal back to the same negative input, (through a feedback resistor R2) the signal will rise until the feedback current balances out the input current.
Now it's not exactly in balance, as there is a very small deviation that has to drive the amplifier to keep its output up, but for most uses the higher the gain of the amplifier, the lower that deviation has to be.
This circuit has a gain of -R2/R1
If you replace the input resistor in the above circuit with a capacitor. It will pass a current proportional to the change in voltage/time and the capacitance. If you feed in a steadily rising voltage, you'll get a current into the negative input of the amplifier that is proportional to the derivative of the input voltage, the feedback current will balance this out, and you'll thus end up with a scaled up derivative of the input.
This circuit has a gain of dv/dt * -R2/(1/c)
If you start with the first circuit and replace the feedback resistor with a capacitor, you'll find that the output has to rise at a rate proportional to the input voltage to balance the input, making an integrator. This only works up to the limit of the output voltage, and there may be a small amount of uncorrected input bias.. to counteract this, a large resistance will be placed in parallel to the capacitor, to keep the output from becoming pegged with no input.
This circuit has a gain of -Integral(Vin)* (1/C) / R1
Notice in all of these equations, the gain is the ratio of the -feedback impedance/input impedance
As an addendum, I'd add that Sedra and Smith wrote an amazing textbook on semiconductors that I highly recommend anyone interested in the topic should read. Here's an Amazon link to the book: https://www.amazon.com/Microelectronic-Circuits-Electrical-C...
I think a better way to go through the exercise is to remember the principles of an ideal op amp: The inputs have infinite input impedance and zero voltage drop across them.
You can derive the behavior of op amp building blocks from these rules and Kirchoff's laws. It also makes things obvious, like ideal vs practical integration.
That works for people who just trust formulae, but for those of use with a background in breadboards and solder, the real world behavior of op amps isn't perfect, and we need to understand it in terms of what we already know.
I'm going through the same learning curve with quantum gates. Nobody shows the physical layout of the devices involved, signals going through them, etc.
Ultimately an op amp is a hardware abstraction. Often you teach the abstraction first through its interface to understand how it allows building useful things. Then you can teach the implementation behind that interface, and all the design trade offs. And just like the formulae, you need to understand that it's a tool for simplification - distrust shouldn't come into play, just proper understanding.
At least in my EE undergrad we were taught why you would want an op amp before we were taught how to design multi stage amplifiers with discrete transistors. In fact most of the real world limitations of op amps don't require knowledge of what's going on under the hood, least of all the physical layout of the chip. Even a schematic diagram of the simplified model for a UA741 is more than you'd ever need except for a shitty SPICE emulation.
I empathize with what you're getting at, but I've seen that mentality turn into the bane of practical or working knowledge of many technical topics. It is a skill to be able to learn just what you need to learn and decide what level of detail is enough, and most of the time that skill is only provided through instruction and mentorship.
I can't reliably figure out the Big O notation of an algorithm for the life of me. I can compare two implementations and tell which is better/worse, but actually calculating it? Not gonna happen.
I struggle with this sometimes, too. There are some examples that are very easy, but others that are very difficult.
For example, finding a word in a dictionary. One algorithm is to start at the beginning and read all the way through until you find it. Worst case scenario, you read all N records, thus it's O(N). A binary search would start 1/2 way through, then repeat with either half, depending on which branch you take, and you wind up with a worst case scenario of O(log N). Nested for loops often wind up as O(n^2).
Beyond that... I have a hard time being any more detailed than the ones I just mentioned.
Well it can get hard sometimes. Ill assume you dont get the basics and try to explain them to you.
For the sake of simplicity, it's just all about getting a ballpark of the resources an algorithm take (often time, can be memory too) without taking into account the specificity of the machine the program runs into.
Let say the algorithm is x+1, x being a number. Now, you can certainly tell that whatever is the computer, it should be fast right. It's O(1). 1 here means, we know it takes one number (x) to compute the result. Wait you gonna say, it takes 2 actually, x and 1. Well yeah, it's 2 then. But it's always gonna be 2. Its not gonna be 3, its not gonna be 4, its gonna be 2, always.
Lets take another example of O(1): x+y+1. How many operations here? 3. Always 3.
So its always a constant number of operation and we call that O(1).
Now let say we have the following algorithm: result = 0, for each x in L: result += x
How many operations? Well now, it depends on the size of L and if L is big, its gonna take a while to compute. Its not a constant anymore. We call that O(N). N here means: the ballpark is: the size of a list. Its not a constant number of operation, its a number of operation the size of a list.
Now, say you have: result = 0, for each i in L: for each j in M: result += i-j
Whats the ballpark here? The size of a list multiplied by the size of another list. So O(N*N) or O(N2).
Now youll find some algorithm runs at O(log N) on average for example. It means its in the ballpark of the size of a list but...no; weve been able to prove that its quite better than that. Say you search in a binary tree, on average, chances are you wont visit all nodes. On average the ballpark is better than the size of a list. Its log N. Why log? Because its a binary tree and binary trees divide by 2 the size of the remaining list after each step or operation.
Whats the ballpark? O(2N) you might say. Nah, its like saying that x+1 is O(2), you re not giving me the ballpark here. What matters is how fast it grows when we put in more inputs. We dont care how many operations there is exactly.
It's O(N). Think of it like, whatever are the details, we have traversed one list, the concatenation of L and M. Weve just traversed lists sequentially, its in the ballpark of traversing one (think of it as a big one if you need too) list. O(N).
I dont get why people say (with reason, Im not contesting) time passes slowly for a fast-moving object. Since there is no fast moving object since its all relative. My (wrong) understanding is that when you observe a fast moving object (relative to you then) then you should perceive this object as moving slowly in time. And my understanding is that we all go to the speed of light, since its all relative (which would explain why e=mc2).
There is a bit I dont get in there. Namely, its relative but its not. I also have to admit I never tried hard to learn more about it.
> Since there is no fast moving object since its all relative.
I don't know if it will help you, but the explanation that worked for me was: "If two events occur at the same place in an inertial reference frame, the time between the events will be shorter than in any other inertial reference frame."
In other words, each observer sees time slow down on/in objects that are moving fast relative to them (i.e. greater time between events).
For example, if a spaceship zips past Earth at nearly the speed of light, someone on Earth will see the clocks nearly stopped on the spaceship, but someone on the spaceship will also see clocks nearly stopped on Earth. As you said, it's all relative - including time.
Edit: As you brought up the twin paradox in a now deleted question, I should point out that this is indeed "wrong" (or just not applicable) to that scenario. This analysis is only for inertial reference frames and ignores perceptual differences due to moving toward or away. The twin paradox introduces a really mind blowing idea called the relativity of simultaneity. Basically, all the asymmetry in the twin paradox is introduced while turning around.
Basically, all the asymmetry in the twin paradox is introduced while turning around.
Cause light goes at speed of light. Nice.
Im intrigued by matter now. What is it exactly it does to a photon if I attach some to it. Edit: or more like, time must be why a photon doesnt teleport (or even exists), so matter does something to time. Matter and gravity must be the same thing or something.
Is there other things/particles going at the speed of light in a vaccum? If no, why? Whats so special about those photons? Could there be (in the maths at least) things/particles going at no speed whatever is the referential frame (in other words they are always in your frame like if they were infinitly distant from everything)?
I have another question that's burning me. Has velocity always the same magnitude in space-time? Or rather (cause certainly not), can an object "trully" have varied velocity in space time (other than in terms of direction)?
I'm not sure of your exact problem, so this might not be helpful, but learning about the reflog in Git accelerated my learning Git because I was no longer fearful of getting my repo into such a state, as I knew the reflog would get me out of trouble, i.e. I could try most any old Git op knowing that if I stuffed things up, I wasn't doomed to re-clone.
With Git everyone has their own personal repository on their machine. Like you could “break away” and be “the central repo and people could start syncing from you. So like remember it’s all “self contained repos” you’re just syncing changes from “somewhere upstream”
Make sure you’re merging changes from your upstream regularly.
When two people change the same area of code, you get a merge conflict.
So sync often and merge often. Don’t wait until you’re ready to push to merge upstream or you’re gonna have a bad time.
No one seems to be answering the second question, so I'll take a crack at it:
When something just isn't clicking in my brain I move on from it! Then some time later (not a fixed time) I happen across it and read through it again with a fresh mind.
This has happened too many times for it to be a coincidence, that the 2nd attempt ALWAYS makes things click very naturally. It has happened with probability concepts such as Bayesian networks or HMMs, optimization algorithms like EM, Monte Carlo sampling, bootstrap, functional programming concepts like monads, C++ move semantics; the list goes on.
Whenever you're stuck, just take a break! And not a 30 minute coffee break but still at the back of your mind kind of break - completely forget about it and come back in a few days, a few weeks or even a month or 2 later
Agreed. I've never really gotten into neural networks, most of the times I start but get distracted or bored/lost and suddenly enough a Vertiasium video pops up and about everything just slots into place, stuff you've glossed over or heard before just make sense. https://www.youtube.com/watch?v=GVsUOuSjvcg. Start at minute 4:00.
Indeed. I prefer going for a run or playing a sport as it completely shifts the focus of your mind as well as the body. I have also noticed that cooking can also be a good mind shifter.
College was immensely frustrating to me for this reason. You can’t just put it on the back burner for a few months (or even weeks): you have quizzes and exams coming up five days from now.
I’m probably a slow thinker, but there are so many concepts from my engineering textbooks that make perfect sense now that were baffling at the time. There’s something about studying those topics in a relaxed, low stakes environment that makes understanding them much easier.
The first part is finding something people will be spending money on in like a year.
You either have to be in an industry and see the “next major iteration”, “now that this tech exists let’s make it simpler” or you have to talk to a lot of people to find a common trend.
Once you have that you start talking and showing your MVP to people. They will give you product excuses not to buy. Use those excuses to slowly iterate your product to remove those excuses.
If at the end there are no excuses and people aren’t buying your value prop isn’t strong enough.
Start with “why are people allocating budget here when they could allocate it to something else” … it needs to affect the bottom line somehow because someone who’s buying your product needs to make a business case internally.
So find a trend, iterate on the product, make sure there’s a “reason to spend money on your product instead of another product”
I understand the math, but I cannot form an intuitive understanding of why it works. My brain just insists that it shouldn't matter how fast you're going, you have a certain amount of energy in your fuel, and that's all there is to it.
Your fuel is measured in delta-V—the velocity you can accelerate by in an inercial reference frame—and kinetic energy scales with the square of your velocity.
But the energy of the spacecraft is not static. As the craft falls towards a body it is trading gravitational potential energy for kinetic energy. Thus the fuel/reaction mass gains kinetic energy along with the rest of the craft. So at the lowest point to the body that reaction mass has the most kinetic energy.
From here it could go two ways:
a) The craft does nothing. The full mass continues to get higher and the kinetic energy the reaction mass gained is turned back into gravitational potential energy.
b) The craft ejects (maybe by burning) the reaction mass. The kinetic energy of the reaction mass is transferred to the craft. Ejecting the reaction mass slows it down and that speed is transferred to the craft. Now the craft continues with all the energy it had going in, but because it is much lighter less of that kinetic energy is transformed back into gravitational potential energy.
Or think of it this way. You have a big rock at the top of a hill. You roll that rock down the hill and convert 100 units of energy in to kinetic energy.
At the bottom of the hill is a see-saw. The big rock hits it and launches a small pebble. That pebble still only has 100 units of energy, but it's moving much faster than the big rock did.
It is not about getting more energy, it is about shedding mass at the right time to transfer (what starts as gravitational) energy from the fuel to the craft.
Hasn't some information been passed? You flip one bit, and if your observing the other bit you know the first one was flipped? So you know when something was done to the first bit...
> Quantum entanglement has not been able to show any usable information can be passed faster than speed of light.
The key word being: "usable".
You can have two bits of quantum information entangled together so they are always opposite values. Then (while keeping the two bits entangled) separate the two bits and place each inside a box without looking at the bits. Then move the boxes apart to the other side of the world.
Quantum Entanglement says that we can open one box to look at the value of the bit inside that box and know that the opposite box has the opposite value.
Alice opens her box and sees the bit "0", so she knows that inside Bob's box is a bit with the value "1".
So depending on which quantum mechanics interpretation you're using, Alice's bit has to share some information with Bob's bit to determine what each bit's value is.
Depending on the time that the boxes are opened, we have experimentally proved that if information is getting transmitted between the two bits and if it is travelling through the space between the two bits, then it must be transmitted faster than the speed of light.
The problem with trying to use this "transmission speed" to send information is that there is no actual way to send any usable information with it.
We can open a box on our end to see which value we got, but we don't know if we got value because we opened the box first, or if the other person opened their box first. The only way to tell is to go and talk to the other person to tell them the time that we opened the box which in and of itself is slower than light.
Everybody talks about how increasing the money supply means increased demand, which drives prices up. But nobody explains how does this *practically* happen. Prices don't go up on their own, it's the retailers who increase them at some point. So if the retailers' perception of the reality is not accurate (Suppose for example that money was printed "secretly", or that the increase in demand wasn't very apparent) prices won't magically go up, no?
There is a common knowledge component in all those equations that's missing and nobody talks about it. Maybe it's too obvious that I'm overlooking it.
> Everybody talks about how increasing the money supply means increased demand, which drives prices up. But nobody explains how does this practically happen.
Money supply isn't the only thing that does it, but when demand goes up sales go up, the additional production to keep pace with the sales has higher per-unit cost (because marginal costs increase), and everyone in the supply chain raises prices as a result. (That's simplified, a lot of price changes are anticipatory based on predictive singles, but that's the basic process that ultimately acts to align prices even if the anticipatory pricing misses movements.)
Companies compete for resources. When there is more money out there (low interest rates from the Fed) companies will be able and willing to pay more for resources. When that happens it becomes more expensive to create products which lowers margins. Companies need to keep margins at a certain level (effort is related to … is the profit worth it to run this business?) prices need to go up to keep those margins.
Commodity and base resources go up—>retail prices go up
More food will be sold (because why not buy the extra whatever since you can afford it) the better workers will demand more pay (otherwise they can go somewhere else that can afford them.)
It's much like gas exchange/osmosis/pressure. Sure the individual particles aren't "thinking" about the behavior of the macro system but their velocity changes every time they bump into each other and that creates the macro effects of osmosis, pressure, heat etc. In the same way inflation is a macro thing that results from the behavior of individuals.
You can see it with boats and cars today: lots of people now have spare money and buy boats/cars -> people selling see that they can charge more (because there are fewer being sold, the ones that do get sold go for more etc) -> boats/cars are more expensive.
In a normal room, the hottest air goes to the top of the room and the coldest air settles to the bottom, right?
However, if the room were to keep expanding, then there is more room at the top for the warmer particles to escape to. Since you stay the same height, the room will feel colder and colder to you even though the total amount of heat in the room stays the same.
As time goes on, unless the room's expansion is stopped or reversed, or temperature treated air is blown into the room to compensate for the difference or, failing that, platforms are provided that will raise you up from the colder areas into the warmer areas, you will eventually freeze to death as the ceiling steals all of the heat of the room, all because you cannot grow with the room.
This is a pretty good example - now just apply it to the actual problem. The amount of currency in circulation.
Inflation isn't about the cost of goods or services actually costing more. They don't. If anything, the cost of production today is far less than it was 50 to 100 years ago because of advances in technology and automation.
It's about the value of the dollar becoming less and less - because there are too many dollars in circulation, which aren't backed by anything real to begin with. "Real" could be something which has a finite supply that we attach an arbitrary value to, like precious metals, or it could be something vitally (needed for life) necessary in today's world like wheat or oil. But for decades now, newly created currency is just an entry in the Fed's ledger book, created out of thin air, backed by nothing.
In your example both the size of the room and the heat represent aspects of currency (note I did not say "money"). The size of the room is the purchasing power of dollars leveraged against the actual effectiveness of the heat. The heat itself, is the value of the currency. The size of the room represents the price of goods.
As the room gets bigger, the heat becomes less effective (it loses value). So pumping in more heat becomes required. When more heat than necessary gets pumped in (on purpose - and it is done on purpose), the room will begin to overheat and no one will want anymore (so it loses its value again). The sane solution would be to stop pumping in more heat - but instead, the same people supplying the heat decide to enlarge the room again, because they are in the business creating heat and charging a fee to deliver it ("they" would be the Federal Reserve - or any private, western central bank).
So the room (i.e. price of goods) must be enlarged over and over again (artificially and unnecessarily) in order for a new infusion of heat to have any value to the people in the room. This in turn, requires the occupants of the room to keep forking over more money in delivery fees to keep the room at a comfortable temperature. If this becomes unfeasible, they may be forced to take out loans to have more usable heat. Now they're paying money for both the heat itself, plus interest on the loan for supplying it in the first place (and they owe it to the same people).
Once you wrap your ahead around the fact that the enlarging of the room and the supply of heat are actually controlled by the same people (who make their money creating heat and charging to deliver it), you then understand that the entire financial system we currently enjoy, is nothing but a giant, legalized system of usury. That delivery fee you owe for supplying the heat is called "interest".
This type of system will always (and is designed to) collapse at pretty regular intervals. When it does, those who control the flow of heat will shut it down, and have legal authority to confiscate the room from the occupants who took out loans for more heat, but couldn't afford to pay it back.
What makes the whole thing more insidious, is that the people supplying the heat never actually owned it to begin with, nor did they create it. It would be as if the room (once upon a time) had a natural heat supply from, say, and underground geothermal source. But some strong-armed, outside entity stepped in, capped that off, and started charging the people in the room for access to what was once naturally available - free of charge.
If you want specific information on the exact phenomenon you’re describing, read up on the “quantity theory of money.”
While academically, it is not a precise concept of what happens in practice, as there are multiple factors at play, printing money nonetheless does have this effect.
Organizations’ ability to increase prices as a result of inflated money supply is governed by competitive forces. So, it’s not as simple as seeing money supply increase 40% and thusly increasing your prices, but there is some truth to it.
I'm a 5 year web developer and I can't understand what web3 is, after spending about 15 minutes trying. Good luck to those senators who try to understand or pretend to understand it.
Instead of big tech giants like FB and Google controlling big centralized databases, you should use a decentralized (but defacto centralized) database that is less efficient.
Instead of recording transactions of a coin on the blockchain, you are storing web3 app data on the blockchain. Unlike a centralized DB controlled by corporations/organizations, it is distributed just like all the nodes in ethereum(for e.g). That was how it was explained to me.
Most anything mathematical. Monads, kalman filters, algebra, calculus.
Also, how people are able to practice and improve at something, like practicing guitar and eventually being able to hit every note, or being able to never leave their wallet behind, or stopping at every stop sign and never forgetting which pedal is the gas.
The fact that people are capable of developing true "skills", where they can do every detail of something, every time, rather than just the vague familiarity a modern programmer needs to get by, just amazes me.
I don't think I've ever truly acquired a new skill in the sense people usually talk about. I can't draw, paint, carve, drive, juggle, dance, etc. I can't cook without a timer, unless I stay in the room and don't do anything else.
If something has a way to fake it with more tech, I'm pretty good at that. As long as I can hide behind the screen with my undo button, where my ability with my own hands is irrelevant, I'm fine.
But there's nothing I can just do without thinking.
I never know where I am. I run into tables all the time. It must be super cool to be able to just do stuff without planning every moment, and still succeed most of the time.
Practicing and actually getting better just by doing something, rather than through research and accumulating a library of patterns, is a totally foreign idea.
> Also, how people are able to practice and improve at something, like practicing guitar and eventually being able to hit every note, or being able to never leave their wallet behind, or stopping at every stop sign and never forgetting which pedal is the gas.
That is something I can relate to. I do most things without really thinking and usually do pretty well, but this makes building skills in the long run very hard since I don't really think much. I don't really know why but I feel like thinking while doing things in the moment is hard for me.
Nope, I have essentially zero spatial abilities. I get left and right confused constantly, and frequently write letters backwards(In addition to writing totally unrelated letters if I don't stop and think about each one)
I also can't really rotate something. When I spent a few hours with a driving simulator game to see if it was at all possible one big issue I had was not being able to figure out which side was the right side of the road, relative to the new perspective after a turn. So I turned straight into traffic more than once.
Pretty sure I just have dyspraxia, which is one of those dyslexia/add/etc type conditions that doesn't have any drug or surgical treatment aside from occupational therapy and always having 100 different backup plans.
But there's GPS apps now so aside from driving and math it's not that limiting. If they ever fix the public transit here I'd probably be fine...
181 comments
[ 4.8 ms ] story [ 263 ms ] threadSpin can then arise from enhancing the Schrödinger equation with a relativistic description of mass and impulse [0].
[0] https://en.wikipedia.org/wiki/Dirac_equation
I get the description of planets in gravity wells and can understand the basic technical explanations.
But it still just doesn't make rational sense on any level to me since I view time and gravity as static concepts from my experiences.
My first major step was to really understand that gravity is a law and not a force.
This is totally counterintuitive since we feel gravity as if it were a force, and because many people use the expression "force of gravity".
So a mass should be viewed as a "tag" that an object has - and the higher the number on the tag, the higher it deforms the space-time around it.
My second major step was to understand that all objects, for example planets, always go straight along a line. They appear to have an orbit because they move in a space-time that is deformed by other planets and mainly stars or black holes.
The moon goes along a straight line in its space-time. But the latter is deformed by the mass of Earth so it looks to us living in Earth's space-time that the moon is orbiting around Earth.
The third major step is to understand that the two space-times mentioned (the Moon's and Earth's) are not "related". Someone on the moon lives in a different space-time than someone on Earth.
So the duration of time that person lives on the Moon as measured by an atomic clock he/she brought will diverge with an atomic clock on Earth.
The difference won't be huge, in truce very very small - but measurable.
Everyone of us lives in its own space-time. Because the gravity is not equal on the point of Earth surface. Because of mountains, and because the Earth itself is not homogeneous, and because we move around and up and down all the time.
In final, this means to get rid of two related notions that appear so self-evident that it is almost impossible to really get over with: - there is a common 3D space that we all share ; - there is such a thing called time that is totally independent and flows continuously.
What really exists - for each person or object or planet - is its own space-time.
And all these space-times are unrelated to each other.
The proof of it is that there is a maximum speed limit to any existing thing. That maximum speed does not vary whatever are the speeds of two considered space-times.
The only thing we know that reach that maximum speed happens to be the light in space.
If the two space-times were related, then the speed of light would vary if one space-time is moving in a different direction and/or speed relatively to the second considered space-time.
But it doesn't. So you and me don't share the same space-time. So, between two encounters, we won't have lived exactly the same duration of time. Our personal atomic clock, if synchronized at the first meeting will have diverged when we meet again.
Of course, the difference will be so super small that it's unnoticeable to us (but measurable with today's technology).
GPS satellites orbite at around 36,000 kms from Earth. That's far enough to make GPS calculations quite wrong if Einsten's relativity is not taken into account (by around 50 meters). That is noticeable.
By the way, Einstein deeply regretted his poor choice of words. Because its theories of "relativity" precisely demonstrate that the different space-times are NOT related.
We need to understand that space and time don't exist. Only unrelated space-times co-exist, within which time as we feel it flows at a different pace than in other space-times.
But there is only one "Reality", right? Well... that really depends what we mean by that. The only common point among space-times is the respect of causality.
That sort of reinstates time as we feel it. If A causes B, then B can not precede A.
In a sense, events creates time as we know it. After all, we are all very often surprised by the time it is on our watch. So this "unstoppable Time that flows no matter what" that we think as self-evident in our representations ... just doesn'...
You have thought about this plenty. The only thing I'll add is that all objects live in the same spacetime. The metric of that spacetime is a mathematical object that obeys known laws under coordinate transformations, and the parameters of those transformations depends on the energy momentum tensor (likewise an object that transforms...).
Trouble with GR is that the "trivial" solutions are heavy shit. So it goes.
However, think about insane it sounds.
Like if we didn't have the subject physics or if you had to explain it to a medieval king in the 1300's.
They would think we are totally insane.
Because it is different than what our everyday hairless monkey lizard brain sensory organs are reporting to our brains.
That's why I struggle with it.
Cool example of satellites. That actually grounds it in an understandable example.
Also does relativity discount Newton?
Or can it be viewed as an extension?
> Physics is like History. We keep on learning at school things that we know to be at best approximate and very often just plain oversimplification that leads to misrepresentations that are super difficult to correct.
I think all of science is like that. It's continually advancing and changing our views of the universe which is beautiful.
Im going to tell my boss next time I'm late that I'm not late it's just that our space times are subjective and aren't currently synchronized.
It's like a lot of other strong constraints on complex endeavors. If you run with it you can get surprisingly far, but only by twisting your understanding of how to do things. Whether that's good or not seems highly personal though.
1. In traditional (imperative) languages you can have functions that deliberately or accidentally either modify the data they were given or do some other stuff that changes data somewhere else in your program or the computer. Let's take an example of each. Say you have a function that adds two numbers a and b. In imperative languages you could return a+b into b. In other words the sum(a,b) operation would change b. That's not cool in FP: you are (almost never) allowed to change the input you received. This way whenever the function is called with a and b it always returns the sum (otherwise if you call sum(a,b) again you will pass in a modified b).
This makes every function guaranteed to always return the same value for the same arguments. If you accidentally try to change a parameter in your code it will fail.
But you still need to make changes to the world - you do so by chaining these functions and using the output from one as input to the next and so on.
Last but not least, functions that have side effects (e.g. print to the screen) are marked differently and usually their effect is isolated.
FP is basically making all of your inputs and outputs explicit. In OOP if you have some bool on a class that affects what a method does, that private bool is technically an extra parameter for that method, even if it doesn't get passed in. Similarly if a method changes some integer on its parent class, in a sense that integer is technically part of what gets returned by the method.
Functional programming forces you to actively think about all of the extra inputs and outputs of your code. In turn, this helps you avoid unintended side effects from the internal workings of a method etc. and the bugs that they can cause.
While the ideas behind FP are useful and can help you think about your coding in a cleaner way, I also think they can be overdone and taken to almost religious extremes. And it can come with a cost of worse performance, more difficult to write/maintain code, etc. , though done right it can have the opposite effect. Done right, it can also make certain aspects of asynchronous and parallel programming easier to work with.
FP, OOP, and all of the other programming paradigms have useful concepts, but purism for any paradigm can lead to all kinds of problems. The obsession with "state" that you see from some FP evangelists is especially annoying, because it ignores that in almost any useful program there will be an irreducible amount of state that has to be tracked and dealt with.
You are essentially working with functions that receive input and return output, and are not allowed to change anything outside them.
The simplicity is in that you create multiple levels of abstractions by only combining functions: low-level functions do some "dirty" work that the program needs to perform (slice cucumber, open oil, pour oil, add salt, etc); you then combine a couple of such low-level functions in another set of functions - making it a bit more abstract (make salad, prepare table); then you combine these abstract functions into even more abstract ones(prepare dinner), etc. There will be also some "helper" abstract functions that can be reused in different contexts (slice something, open something, put some food on the table, etc).
Because each function - no matter the level of abstraction - only takes input and produces output - it's very simple to write, read, reason about, and test.
Obvious question you might have right now: how can you write a useful program if you can't change anything outside the function or interact with the outside world? Well, that's the "dirty" part of writing a FP program. You just write your program trying to keep it as "pure" as possible, pushing the "dirty" parts away as much as possible. Think Layered Architecture but for programs. You keep the "outer layers" of your program "dirty" - reading/writing to the DB, making network calls, etc - and preserve the "purity" of as many "inner layers" as possible. For example, when you want to write to a DB in one of "inner layers" which should stay "pure" - you can return your "desire to write to a DB" as a string(or however you encode it) to your outer layers, which will then perform the actual operation by actually talking to the DB. The inner function stays pure because it doesn't actually talk to the DB, it only returns instructions for outer layers to talk to the DB.
Depending on the language you are using it might be either beautiful and easy, or extremely awkward and overly complicated. Most of the time it's something in between.
Hope this helps.
What I did was I gave up and no longer click those articles.
Then, try store your programs state by passing it as a function argument to every function so it stays available for the lifetime of the program (no mutable state? This is basically what happens)
After realizing what a pain this is and wishing for boilerplate, look at the State monad. This is what did it for me :)
I'm honestly not even sure what function composition is, or why you would compose two functions instead of just explicitly making a new function that calls the two original ones.
The second one makes more sense because of the rumored bug-freeness of side effect free apps, but it seems like for that too, you'd need to understand a lot more than just monads.
Or in javascript:
function f(x) { return x + 1 }
function g(x) { return x + 2 }
f(g(1)) === 4
In functional languages like Haskell function composition is made easy, because functions can be partially applied. Partial application means that given a function that takes two arguments, I can call it with one argument and it will return a function that takes one argument which returns the result. Whereas in languages like javascript it is difficult because functions can have different numbers of arguments and there's no way to partially apply them or flip their arguments, so it is difficult to chain functions together. And because javascript functions aren't pure, they may not have any result which can be composed with other functions. In a functional language, functions are more like the functions in math. In most non-functional languages, functions are more like a procedure of commands. For example, the javascript function logMe(x) { console.log(x) } doesn't return anything. So it can't be composed functionally, and is not like a "real" function.
When we want to "compose" two functions, there's f(x){return a(b(x))}.
It doesn't matter if the signatures are different, you don't need any nice logical idea of composition, you just explicitly build the new function that does what you want.
I would say that is a lot easier than real composition, because real composition requires you first learn to see and think in terms of patterns you would want to compose in the first place.
Also, function chaining doesn't use intermediate variables. Named variables are like free documentation. With composition you have to actually remember what you're doing. Making everything explicit makes it easier to comment what's happening.
Regular programming is to math as cooking is to chemistry. Functional brings the math back to programming. Math is useful but also hard.
In OOP, more often you're doing the equivalent of:
if crinkle(a(b(x,68), modes.FOO).bar.baz(9)): x = foo() else: x = wipe(7).bar()
And I think it's a lot nicer to just spell it out with meaningful variable names, instead of trying to compose it like an equation.
You have standard functions like bake and boil, and they don't tell you to use clean utensils or how to turn the stove on, because an cooking is basically just a few dozen standard functions, end condition rules, etc.
If you think of them as programs, the composition they use isn't the same as functional languages, because the individual steps are unstructured and there's no generalized abstract pattern defining what a RecipeStep is or what composing two of them means.
You wouldn't say add(flour(add(salt,empty))), you would say "add flour, salt, water, and yeast".
"add" can take either an ingredient or a list, and it's pretty encapsulated, since it dynamically selects a way to measure the ingredient based on what it is, what utensils you have, etc.
It could trigger dozens of unrelated code paths based on state, and probably includes error recovery.
Functional might be nice for implementing the internals of that add() function, but in OOP the idea seems to be that it's a pretty minor detail, since add() is only written once and rarely changed, but used millions and millions of times all over the world for a decade.
Usually when people talk about "the beauty of functional" I get the impression that they're not really doing a whole lot of "One really smart function that knows exactly what to do" level abstraction.
It seems like they'd literally be composing together their own variations of what "add" is, as needed from the raw findMeasuringStrategy and checkPantry functions instead.
That second example tells the reader that it is doing, which may or may not be what it was supposed to be doing.
As a maintainer, I prefer knowing that:
is supposed to result in a salted batter, which the first code block tells me but the second one does not.For write-only code, sure, that's great.
It's irrelevant when I am tracking down a bug - the label 'saltedBatter' tells me what that intermediate result is supposed to be.
If, when debugging, I find that `add(salt, batter)` results in something else[1], using your convention it is literally impossible to tell that the value is supposed to be `saltedBatter`.
There is literally no way to tell if the intermediate values are correct. Maybe each caller in the composition chain can throw an Exception?
The point is, the variable names are helpful.
> but only the first and last step have a name because the intermediate steps are just that.
That describes the entire program :-)
In all seriousness though, it's because you intend to describe steps in the process that throwing away all labels for the intermediate steps makes sense.
You're describing verbs. We don't need to know the in-between verbs for a verb. When you call `driveTo()`, it is not necessary to know all the verbs involved in that action, it is enough to know that it will attempt a certain action.
Verbs answers the "what we are doing" questions.
Variable names answer the "Why we are doing it" questions - `saltedBatter = foo (bar(), baz);` tells the reader why foo is being called.
We don't even need to know the steps involved or even what the other variables (used as parameters) should be. Assigning the result of a function to a variable ensures that the maintainer knows if that variable ever holds the wrong value.
I think where a lot of this value (variable-names) is lost is in enterprise development - the names are never helpful, they're just a differently-cased version of the type. Like these gems I see daily:
So, yeah, I see your point if all you ever see is enterprise-grade naming conventions. OTOH, if those above two lines were written as: you, as the maintainer, know exactly what that last line is supposed to do, and if it isn't doing that, then you know it's a bug.Compare with this:
Or, if you wanted descriptive function names: Brevity is not a virtue in programming languages and/or programs. It's probably why Haskell is still not even a rounding error as far as popularity goes.[1] Maybe `doubleSaltedBatter`, in case an upstack caller used `saltedWater` in place of `water`, or perhaps `pepperedBatter` in case a caller switched out the salt for pepper.
Real world Haskell code isn't the codegolf you are implying.
In fact, I think real world Haskell devs overcorrect and make code too verbose.
Also, "brevity is not a virtue in programming languages" is something I disagree with.
Walls of verbose code are just so damn mentally taxing. Especially hen you finish reading and saybto yourself "all that code just to do X?".
So is working with an edifice of unprincipled ad-hoc abstractions, but many seem to prefer pushing that debt on tomorrow them or others.
I'm not clear why the next function in the pipeline would need to know about the error rather than the caller, but that happens with promise chains too
https://medium.com/swlh/monads-in-python-e3c9592285d6
Exceptions usually aren't typechecked.
All I know is they contain values and you can pass them functions, and somehow by doing this you can write fully pure programs with supposedly fewer bugs, and Haskell programmers seem to not understand why this is hard.
The way I understand monads: some data structure plus 2 functions, "return" and "join":
- "return": wraps something with the data structure. (no relation with the return keyword you are used to in most languages)
- "join": joins 2 layers of the _same_ data structures into one.
And that's it. It's just that simple what a monad is: in java it would be an interface with just these two methods.
Examples:
- "return" for List: takes a value and returns a List containing just that value.
- "return" for Maybe: takes a value and returns Maybe value.
- "join" for List: takes a List of Lists and returns a flattened List (2 outer layers joined).
- "join" for Maybe: takes Maybe Maybe value and returns Maybe value.
I think what makes these functional programming concepts hard to grasp most of the times is that communicating the boundaries of abstract concepts is hard in general, even if the concept itself is really simple, like a monad can be for a programmer.
As for why monads are useful, the explanations you can find online give a lot of examples. Just think of all the times you may have used flatmap for arrays: that's just map followed by the "join" for arrays, which is sometimes called flatten. The other operators you see used in haskell, like "bind" (>>=), can be derived from "join" and vice versa and are just conveniences to write code with less noise, like flatmap is.
Recap: monad is the name of the concept for things that have a "join" and a "return" functions defined. Basically "join" is the distilled concept of what a monad is.
[1] https://haskellbook.com/
(edit: formatting)
It explicitly tries to answer the question: "I’m a C# programmer with no “functional programming” background whatsoever. What is this “monad” thing I keep hearing about, and what use is it to me?"
I have an article i'm about to publish that will have a lot more real world examples... hopefully it can bridge the gap.
It'll also have exercises, which are honestly the most important part of understanding.
https://www.youtube.com/watch?v=t1e8gqXLbsU
I’m a self-taught programmer, so have probably missed lots that might help, but every time I come across anything OO, it always seems unnecessarily complicated and awkwardly structured. It always seems (to me) that everything could be done more simply procedurally. I don’t get why.
Further, while I can follow OO code that others have written, as a beginner, how to structure something simple I’m writing de novo in an OOP style has a very steep learning curve.
Some people are really good it but it's a skill for sure and learning it is rough. It is some really abstract thinking shit, and difficult even to evaluate how well it has been done until much time has passed with it.
I think when people joke about naming in programming this is what they mean. Needing to clearly define relations that are not necessarily clear yet. OOP does demand a lot of that so is hard and exhausting in a particular way.
That said nothing against OOP I use it every day and Sandi Metz is the code book writer I learned the most useful stuff from. Just it's hard in a different way from most of the rest of coding.
Android development is the classic example - it's ALL OO - and most of the time, that's pushing the proverbial uphill. Instead of just initialise something, everything is pushed into constructors. The model works sometimes, but for many things it just adds work. AND ADDS ENORMOUS AMOUNTS OF BOILERPLATE. Aarrgghhh.
But in modern OOP, understanding and simplicity are not what it's all about.
It's all about pushing the complexity into the language runtime stuff where it is no longer your problem.
OOP is popular because we can do stuff like port=DBConnection(); port.connect("foo.baz") and document= port.request("x").
Then, later on, when port and document are inaccessible, garbage collection will get them.
An OOP programmer doesn't think "Oh, the port.connect must make a socket and do a handshake and then..." they just think "It does all the port connect stuff".
As a student when the goal is to understand, OOP makes no sense, because encapsulation literally is all about making it so you don't need to think about things.
It lets you treat objects the same way we treat physical devices. Black boxes someone else built.
There's no beautiful reasoning or amazing objective logic saying OOP is better than I know of, or anything that even makes any sense at all if you think about it.
It just happens to work pretty well when people with a wide range of skill levels do large projects and nobody understands anything beyond their tiny part, and nobody really cares if things are simple under the hood.
If you want beauty and logic, learn a pure functional language or go study math.
And if you want to structure stuff in an modern OOP style, you just stop thinking in terms of simplicity and unified wholes and start thinking in terms of black boxes to be used by people who would be annoyed if they actually had to read the code.
Any entity you would talk about when describing the code is something that could be represented as an object.
Any collection of a variable number of a ton of entities like customers is something you could do as some kind of database connection object.
Any periodic task might be a "Machine" that is a class that manages a thread.
It's(In theory) a 1 to 1 mapping of ideas to classes, although some things just aren't worth a whole inventing object for and should probably be a data dict+procedural.
But, some would say this whole thing is nonsense for idiots who can't think, so maybe if you find yourself actually able to do procedural well you should try something more logical like haskell.
doX(data, args)
Here is OO:
data.doX(args)
The only difference is that you can stop doX(data, args) from modifying parts of data. However you can do the exact same thing in non-OO languages like C or Haskell by using void* (in C) or (in Haskell) modules with hidden constructors.
The only true OO language out there is Erlang. C++/Java/C# etc. are not OO languages.
The idea that OO is modelling the world is BS. You don't ask your shoe to tie itself or ask a tree to chop itself.
And you don't ask an integer to display itself in a dialog in an "OO" language unless you are a bad software designer.
- How opamps work and how they're used to make a differentiator.
- How quantum computing works. I want understand it to understand why factoring and discrete log fall to QC but not the post-quantum algorithms. I never make it past the intro chapters.
- What exactly makes cryptographic hash functions have desirable properties like collision resistance? Bits go in, bits go out, why can't full observation of the process not yield a method to construct inputs for a target output? Similar questions for block ciphers. It is much easier to "see" the impossibility in public key schemes because you can play and experiment with the math. In symmetric algorithms it looks like just a bunch of arbitrary bit operations.
EDIT:
- Relativity. I accept things like time dialation and nothing can go faster than the speed of light. But I have no idea why you would experience less time passing than me after a high speed rocket trip when, from your perspective, you saw me on a high speed planet trip. Or what prevents a rocket in space with 3m/s^2 acceleration from reaching the speed of light after 100,000,000 seconds.
An op-amp is just a very high gain amplifier. It senses the difference in signal levels and just amplifies that difference by a large amount, usually between 1000 and 10,000,000 times.
The first op-amp circuit you usually use is a negative feedback linear amplifier. In this circuit, the positive input to the op-amp is simply grounded. The input voltage is put through a resistor R1 into the negative (AKA inverting) input. The resistor limits the current into the negative input to Vin/R. As soon as the voltage on the input becomes non-zero, the output of the op amp becomes a quite large signal, of the opposite sign. If you feed a small amount of that signal back to the same negative input, (through a feedback resistor R2) the signal will rise until the feedback current balances out the input current.
Now it's not exactly in balance, as there is a very small deviation that has to drive the amplifier to keep its output up, but for most uses the higher the gain of the amplifier, the lower that deviation has to be.
This circuit has a gain of -R2/R1
If you replace the input resistor in the above circuit with a capacitor. It will pass a current proportional to the change in voltage/time and the capacitance. If you feed in a steadily rising voltage, you'll get a current into the negative input of the amplifier that is proportional to the derivative of the input voltage, the feedback current will balance this out, and you'll thus end up with a scaled up derivative of the input.
This circuit has a gain of dv/dt * -R2/(1/c)
If you start with the first circuit and replace the feedback resistor with a capacitor, you'll find that the output has to rise at a rate proportional to the input voltage to balance the input, making an integrator. This only works up to the limit of the output voltage, and there may be a small amount of uncorrected input bias.. to counteract this, a large resistance will be placed in parallel to the capacitor, to keep the output from becoming pegged with no input.
This circuit has a gain of -Integral(Vin)* (1/C) / R1
Notice in all of these equations, the gain is the ratio of the -feedback impedance/input impedance
Does that make sense?
You can derive the behavior of op amp building blocks from these rules and Kirchoff's laws. It also makes things obvious, like ideal vs practical integration.
I'm going through the same learning curve with quantum gates. Nobody shows the physical layout of the devices involved, signals going through them, etc.
At least in my EE undergrad we were taught why you would want an op amp before we were taught how to design multi stage amplifiers with discrete transistors. In fact most of the real world limitations of op amps don't require knowledge of what's going on under the hood, least of all the physical layout of the chip. Even a schematic diagram of the simplified model for a UA741 is more than you'd ever need except for a shitty SPICE emulation.
I empathize with what you're getting at, but I've seen that mentality turn into the bane of practical or working knowledge of many technical topics. It is a skill to be able to learn just what you need to learn and decide what level of detail is enough, and most of the time that skill is only provided through instruction and mentorship.
http://www.av8n.com/physics/spacetime-welcome.htm
For example, finding a word in a dictionary. One algorithm is to start at the beginning and read all the way through until you find it. Worst case scenario, you read all N records, thus it's O(N). A binary search would start 1/2 way through, then repeat with either half, depending on which branch you take, and you wind up with a worst case scenario of O(log N). Nested for loops often wind up as O(n^2).
Beyond that... I have a hard time being any more detailed than the ones I just mentioned.
For the sake of simplicity, it's just all about getting a ballpark of the resources an algorithm take (often time, can be memory too) without taking into account the specificity of the machine the program runs into.
Let say the algorithm is x+1, x being a number. Now, you can certainly tell that whatever is the computer, it should be fast right. It's O(1). 1 here means, we know it takes one number (x) to compute the result. Wait you gonna say, it takes 2 actually, x and 1. Well yeah, it's 2 then. But it's always gonna be 2. Its not gonna be 3, its not gonna be 4, its gonna be 2, always.
Lets take another example of O(1): x+y+1. How many operations here? 3. Always 3.
So its always a constant number of operation and we call that O(1).
Now let say we have the following algorithm: result = 0, for each x in L: result += x
How many operations? Well now, it depends on the size of L and if L is big, its gonna take a while to compute. Its not a constant anymore. We call that O(N). N here means: the ballpark is: the size of a list. Its not a constant number of operation, its a number of operation the size of a list.
Now, say you have: result = 0, for each i in L: for each j in M: result += i-j
Whats the ballpark here? The size of a list multiplied by the size of another list. So O(N*N) or O(N2).
Now youll find some algorithm runs at O(log N) on average for example. It means its in the ballpark of the size of a list but...no; weve been able to prove that its quite better than that. Say you search in a binary tree, on average, chances are you wont visit all nodes. On average the ballpark is better than the size of a list. Its log N. Why log? Because its a binary tree and binary trees divide by 2 the size of the remaining list after each step or operation.
for each x in L: result += x
for each x in M: result -= x
(Loops arent nested here but done sequentially)
Whats the ballpark? O(2N) you might say. Nah, its like saying that x+1 is O(2), you re not giving me the ballpark here. What matters is how fast it grows when we put in more inputs. We dont care how many operations there is exactly.
It's O(N). Think of it like, whatever are the details, we have traversed one list, the concatenation of L and M. Weve just traversed lists sequentially, its in the ballpark of traversing one (think of it as a big one if you need too) list. O(N).
There is a bit I dont get in there. Namely, its relative but its not. I also have to admit I never tried hard to learn more about it.
I don't know if it will help you, but the explanation that worked for me was: "If two events occur at the same place in an inertial reference frame, the time between the events will be shorter than in any other inertial reference frame."
In other words, each observer sees time slow down on/in objects that are moving fast relative to them (i.e. greater time between events).
For example, if a spaceship zips past Earth at nearly the speed of light, someone on Earth will see the clocks nearly stopped on the spaceship, but someone on the spaceship will also see clocks nearly stopped on Earth. As you said, it's all relative - including time.
Edit: As you brought up the twin paradox in a now deleted question, I should point out that this is indeed "wrong" (or just not applicable) to that scenario. This analysis is only for inertial reference frames and ignores perceptual differences due to moving toward or away. The twin paradox introduces a really mind blowing idea called the relativity of simultaneity. Basically, all the asymmetry in the twin paradox is introduced while turning around.
Cause light goes at speed of light. Nice.
Im intrigued by matter now. What is it exactly it does to a photon if I attach some to it. Edit: or more like, time must be why a photon doesnt teleport (or even exists), so matter does something to time. Matter and gravity must be the same thing or something.
I wish I had time to study, love it.
Make sure you’re merging changes from your upstream regularly.
When two people change the same area of code, you get a merge conflict.
So sync often and merge often. Don’t wait until you’re ready to push to merge upstream or you’re gonna have a bad time.
[0]: https://tom.preston-werner.com/2009/05/19/the-git-parable.ht...
When something just isn't clicking in my brain I move on from it! Then some time later (not a fixed time) I happen across it and read through it again with a fresh mind.
This has happened too many times for it to be a coincidence, that the 2nd attempt ALWAYS makes things click very naturally. It has happened with probability concepts such as Bayesian networks or HMMs, optimization algorithms like EM, Monte Carlo sampling, bootstrap, functional programming concepts like monads, C++ move semantics; the list goes on.
Whenever you're stuck, just take a break! And not a 30 minute coffee break but still at the back of your mind kind of break - completely forget about it and come back in a few days, a few weeks or even a month or 2 later
I’m probably a slow thinker, but there are so many concepts from my engineering textbooks that make perfect sense now that were baffling at the time. There’s something about studying those topics in a relaxed, low stakes environment that makes understanding them much easier.
SaaS is useful inside enterprises because you don't have to provision software on machines.
SaaS is useful for entrepreneurs to build businesses by chaining APIs together.
SaaS viz a vi Shopify is useful because smaller business can leverage larger Amazon like tooling.
You either have to be in an industry and see the “next major iteration”, “now that this tech exists let’s make it simpler” or you have to talk to a lot of people to find a common trend.
Once you have that you start talking and showing your MVP to people. They will give you product excuses not to buy. Use those excuses to slowly iterate your product to remove those excuses.
If at the end there are no excuses and people aren’t buying your value prop isn’t strong enough.
Start with “why are people allocating budget here when they could allocate it to something else” … it needs to affect the bottom line somehow because someone who’s buying your product needs to make a business case internally.
So find a trend, iterate on the product, make sure there’s a “reason to spend money on your product instead of another product”
https://en.wikipedia.org/wiki/Oberth_effect
I understand the math, but I cannot form an intuitive understanding of why it works. My brain just insists that it shouldn't matter how fast you're going, you have a certain amount of energy in your fuel, and that's all there is to it.
> at 1 m/s, adding 1 m/s increases the kinetic energy from 1 J to 4 J, for a gain of 3 J;
> at 10 m/s, starting with a kinetic energy of 100 J, the rocket ends with 121 J, for a net gain of 21 J
From here it could go two ways:
a) The craft does nothing. The full mass continues to get higher and the kinetic energy the reaction mass gained is turned back into gravitational potential energy.
b) The craft ejects (maybe by burning) the reaction mass. The kinetic energy of the reaction mass is transferred to the craft. Ejecting the reaction mass slows it down and that speed is transferred to the craft. Now the craft continues with all the energy it had going in, but because it is much lighter less of that kinetic energy is transformed back into gravitational potential energy.
Or think of it this way. You have a big rock at the top of a hill. You roll that rock down the hill and convert 100 units of energy in to kinetic energy.
At the bottom of the hill is a see-saw. The big rock hits it and launches a small pebble. That pebble still only has 100 units of energy, but it's moving much faster than the big rock did.
It is not about getting more energy, it is about shedding mass at the right time to transfer (what starts as gravitational) energy from the fuel to the craft.
I knows this is a dumb question but please pardon me as my knowledge of physics is very limited.
So for example, if two bits are entangled, you flip one bit, the other bit flips at a completely unpredictable way.
Hence, no rule is technically broken.
The key word being: "usable".
You can have two bits of quantum information entangled together so they are always opposite values. Then (while keeping the two bits entangled) separate the two bits and place each inside a box without looking at the bits. Then move the boxes apart to the other side of the world.
Quantum Entanglement says that we can open one box to look at the value of the bit inside that box and know that the opposite box has the opposite value.
Alice opens her box and sees the bit "0", so she knows that inside Bob's box is a bit with the value "1".
So depending on which quantum mechanics interpretation you're using, Alice's bit has to share some information with Bob's bit to determine what each bit's value is.
Depending on the time that the boxes are opened, we have experimentally proved that if information is getting transmitted between the two bits and if it is travelling through the space between the two bits, then it must be transmitted faster than the speed of light.
The problem with trying to use this "transmission speed" to send information is that there is no actual way to send any usable information with it.
We can open a box on our end to see which value we got, but we don't know if we got value because we opened the box first, or if the other person opened their box first. The only way to tell is to go and talk to the other person to tell them the time that we opened the box which in and of itself is slower than light.
Everybody talks about how increasing the money supply means increased demand, which drives prices up. But nobody explains how does this *practically* happen. Prices don't go up on their own, it's the retailers who increase them at some point. So if the retailers' perception of the reality is not accurate (Suppose for example that money was printed "secretly", or that the increase in demand wasn't very apparent) prices won't magically go up, no?
There is a common knowledge component in all those equations that's missing and nobody talks about it. Maybe it's too obvious that I'm overlooking it.
Money supply isn't the only thing that does it, but when demand goes up sales go up, the additional production to keep pace with the sales has higher per-unit cost (because marginal costs increase), and everyone in the supply chain raises prices as a result. (That's simplified, a lot of price changes are anticipatory based on predictive singles, but that's the basic process that ultimately acts to align prices even if the anticipatory pricing misses movements.)
Commodity and base resources go up—>retail prices go up
Very simplified explanation.
More food will be sold (because why not buy the extra whatever since you can afford it) the better workers will demand more pay (otherwise they can go somewhere else that can afford them.)
It's much like gas exchange/osmosis/pressure. Sure the individual particles aren't "thinking" about the behavior of the macro system but their velocity changes every time they bump into each other and that creates the macro effects of osmosis, pressure, heat etc. In the same way inflation is a macro thing that results from the behavior of individuals.
You can see it with boats and cars today: lots of people now have spare money and buy boats/cars -> people selling see that they can charge more (because there are fewer being sold, the ones that do get sold go for more etc) -> boats/cars are more expensive.
In a normal room, the hottest air goes to the top of the room and the coldest air settles to the bottom, right?
However, if the room were to keep expanding, then there is more room at the top for the warmer particles to escape to. Since you stay the same height, the room will feel colder and colder to you even though the total amount of heat in the room stays the same.
As time goes on, unless the room's expansion is stopped or reversed, or temperature treated air is blown into the room to compensate for the difference or, failing that, platforms are provided that will raise you up from the colder areas into the warmer areas, you will eventually freeze to death as the ceiling steals all of the heat of the room, all because you cannot grow with the room.
Inflation isn't about the cost of goods or services actually costing more. They don't. If anything, the cost of production today is far less than it was 50 to 100 years ago because of advances in technology and automation.
It's about the value of the dollar becoming less and less - because there are too many dollars in circulation, which aren't backed by anything real to begin with. "Real" could be something which has a finite supply that we attach an arbitrary value to, like precious metals, or it could be something vitally (needed for life) necessary in today's world like wheat or oil. But for decades now, newly created currency is just an entry in the Fed's ledger book, created out of thin air, backed by nothing.
In your example both the size of the room and the heat represent aspects of currency (note I did not say "money"). The size of the room is the purchasing power of dollars leveraged against the actual effectiveness of the heat. The heat itself, is the value of the currency. The size of the room represents the price of goods.
As the room gets bigger, the heat becomes less effective (it loses value). So pumping in more heat becomes required. When more heat than necessary gets pumped in (on purpose - and it is done on purpose), the room will begin to overheat and no one will want anymore (so it loses its value again). The sane solution would be to stop pumping in more heat - but instead, the same people supplying the heat decide to enlarge the room again, because they are in the business creating heat and charging a fee to deliver it ("they" would be the Federal Reserve - or any private, western central bank).
So the room (i.e. price of goods) must be enlarged over and over again (artificially and unnecessarily) in order for a new infusion of heat to have any value to the people in the room. This in turn, requires the occupants of the room to keep forking over more money in delivery fees to keep the room at a comfortable temperature. If this becomes unfeasible, they may be forced to take out loans to have more usable heat. Now they're paying money for both the heat itself, plus interest on the loan for supplying it in the first place (and they owe it to the same people).
Once you wrap your ahead around the fact that the enlarging of the room and the supply of heat are actually controlled by the same people (who make their money creating heat and charging to deliver it), you then understand that the entire financial system we currently enjoy, is nothing but a giant, legalized system of usury. That delivery fee you owe for supplying the heat is called "interest".
This type of system will always (and is designed to) collapse at pretty regular intervals. When it does, those who control the flow of heat will shut it down, and have legal authority to confiscate the room from the occupants who took out loans for more heat, but couldn't afford to pay it back.
What makes the whole thing more insidious, is that the people supplying the heat never actually owned it to begin with, nor did they create it. It would be as if the room (once upon a time) had a natural heat supply from, say, and underground geothermal source. But some strong-armed, outside entity stepped in, capped that off, and started charging the people in the room for access to what was once naturally available - free of charge.
While academically, it is not a precise concept of what happens in practice, as there are multiple factors at play, printing money nonetheless does have this effect.
Organizations’ ability to increase prices as a result of inflated money supply is governed by competitive forces. So, it’s not as simple as seeing money supply increase 40% and thusly increasing your prices, but there is some truth to it.
Also, how people are able to practice and improve at something, like practicing guitar and eventually being able to hit every note, or being able to never leave their wallet behind, or stopping at every stop sign and never forgetting which pedal is the gas.
The fact that people are capable of developing true "skills", where they can do every detail of something, every time, rather than just the vague familiarity a modern programmer needs to get by, just amazes me.
I don't think I've ever truly acquired a new skill in the sense people usually talk about. I can't draw, paint, carve, drive, juggle, dance, etc. I can't cook without a timer, unless I stay in the room and don't do anything else.
If something has a way to fake it with more tech, I'm pretty good at that. As long as I can hide behind the screen with my undo button, where my ability with my own hands is irrelevant, I'm fine.
But there's nothing I can just do without thinking.
I never know where I am. I run into tables all the time. It must be super cool to be able to just do stuff without planning every moment, and still succeed most of the time.
Practicing and actually getting better just by doing something, rather than through research and accumulating a library of patterns, is a totally foreign idea.
That is something I can relate to. I do most things without really thinking and usually do pretty well, but this makes building skills in the long run very hard since I don't really think much. I don't really know why but I feel like thinking while doing things in the moment is hard for me.
I also can't really rotate something. When I spent a few hours with a driving simulator game to see if it was at all possible one big issue I had was not being able to figure out which side was the right side of the road, relative to the new perspective after a turn. So I turned straight into traffic more than once.
But there's GPS apps now so aside from driving and math it's not that limiting. If they ever fix the public transit here I'd probably be fine...