IvoDankolov
Joined 15 years ago
Joined 15 years ago
If you wanted to keep the the ability to link to specific states, but avoid the history issue, you'll need to use the History API — https://developer.mozilla.org/en-US/docs/Web/API/History/rep...
But it's still an approximation, with things like e.g. backpropagation 'simply' (in the abstract mathematical sense) tweaking weights in the direction of the derivatives to get closer to expected values.
The vast majority of machine learning just builds on that by going deep (more layers), automatically generating inputs (e.g. in game AIs playing against themselves), etc.
One might argue that's even worse than function optimisation as you can only vaguely guess at the target and thus all your validation is suspect and you have to prove it using humans by, for instance, beating them at Starcraft.
struct A
{
void f() {std::cout << "A";}
};
struct B : A
{
void f() {std::cout << "B";}
};
//.,...
A a = B();
B b = B();
a.f();
b.f();
b.A::f();
This would print ABA, as the child's f() function simply hides the parent one when working in the context of B(), but it does not override it.Now, what virtual does is it tells the compiler, "from here on out, resolve clashing signatures for this function in child classes by overriding. I'm sure you know how our example changes when you mark f() as virtual.
That's all old news, though. The more interesting bit, final, acts like so: from here on out, prevent overloading in child classes. Now, that only makes sense in the context of virtual, so that's the only place where you're allowed to use final, and here the actual difference to the first example becomes apparent. You see, final does not negate virtual, what it actually does is completely lock up the function signature from being used in any child classes. Adding virtual final to our example would not cause B's function to hide A's - it will simply not compile.
If you think that's all pointless semantics, you are absolutely right. Locking up names is not the point of "final". In fact, declaring something as virtual final in the base class is completely pointless from any practical standpoint. The actual problem that final is meant to solve is this:
As I mentioned earlier, virtual changes the way resolving names works in child classes forever. These two pieces of code are absolutely equivalent.
struct A
{
virtual void f() {std::cout << "A";}
};
struct B : A
{
void f() {std::cout << "B";}
};
And: struct A
{
virtual void f() {std::cout << "A";}
};
struct B : A
{
virtual void f() {std::cout << "B";}
};
Therein lies an interesting dilemma. What if I wanted to prevent any child class of B, and only B, from changing the implementation of f. Under C++03, that is not possible. In C++11, final solves that.But why go through the trouble of introducing a new keyword - and a keyword that is only a keyword in class and function declarations to boot (Holy context dependent grammar, Batman!) - and not just drop the virtual qualifier? Backwards compatibility - ever a dreaded thing when you wish you could undo your old mistakes.
It isn't all that big of a deal (said the C++ developer about every strange rule in the language, ever), though, since when you use "final" for the intended purpose, you won't actually be needing the virtual qualifier.
struct A
{
virtual void f() {std::cout << "A";}
};
struct B : A
{
void f() final {std::cout << "B";}
};
struct C : B
{
void f(); //I'm afraid I can't let you do that.
};- That you can use the name of a variable, h, as if it was a function? That's because Javascript has first class functions [1] - the language is defined to support passing them around as variables and calling them like that.
- That you can use h at all even though it's neither a local variable nor a parameter of the anonymous function? That's because functions in javascript aren't simply procedures in the traditional sense - i.e. description (function signature) + code - they are also closures [2]. If you declare one function inside another, it can capture (have a reference to) variables and parameters of the outer one. You are also guaranteed that local variables and parameters will not get cleaned up while a closure still exists that holds a reference to them.
[1] : http://en.wikipedia.org/wiki/First_class_function
[2] : Can't vouch for any particular article, try googling Javascript closures
What do you make of this problem with distant entangled particles? The double slit experiment and interference in general? The Heisenberg uncertainty principle? (Or as I'd like to call it, Heisenberg's horribly mislabeled-in-order-to-confuse-students principle)
A shot in the dark - many of the problems with coming to terms with quantum mechanics arise from trying to impose on it that it should somehow behave like classical mechanics, or that somehow we humans stand above it and look down upon it, and heaven forbid that we're part of a qunatum system).
I'm still not entirely sure why so many people consider collapse to be simpler. Is it too daunting to think of the world as an amplitude distribution that propagates in a way that we're not intuitively used to? Too hard to think of ourselves as part of quantum mechanics, because that thing I see there on the measuring device must be the reality, damn it, and what the hell do you mean I've just entangled myself and the device along with the system?
Or maybe just tradition and accepting the "scripture" coming from the established authority. How could we best test that?
You see, the problem is not whether you can transfer information in human readable form (though if you could that would certainly be a huge problem with relativity!), but whether any effect that propagates faster than the speed of light exists.
You'll have a hard time explaining that in the frame of wavefunction collapse, I think.
Not that interpreting all of this to mean that physics is non-local "spooky-action-at-a-distance" is the only viable route, mind.
Consider this: why, exactly, do you believe that when you measure the particle you somehow force it to enter one particular state and therefore the entangled one that's sitting X miles away suddenly enters the opposite one? Are we, humans, sitting outside of quantum mechanics and looking down upon it - and then what we observe is the one true way the world is?
Why would you not, instead, when you measure the particle, entangle the measuring device, and yourself, with the state of the particle? You are, after all, only another part of quantum mechanics the same as anything else.
You might think that I'm saying that in jest, but it is actually the way of things. There are quite literally an infinite number of numbers. Why should Graham's be important enough for us to consider. For that matter, why should we consider 1?
The answer lies in part in the question - why - it must be important in some way. That is exactly the case - we only consider numbers that, for some reason, relate to problems we are facing, whether it be in mathematics, programming, or grocery shopping, and even then not on their own merits. Past a certain point, you don't hold numbers in your head as little balls, but rather their decimal encoding. That's a clever hack, but not without its downsides. Ask some people randomly if they were in a position to decide, how much budget would they allocate to save 10000 birds, and ask others the same with 100000 birds. The mean of the second answer would not be ten times that of the first (unless your subjects know and actively try to work around that particular bias).
But back to Graham's number - if you think the only way to imagine it is to hold its decimal notation in your head - the obvious question is why? Why not hexadecimal? Octal? Why any base-p encoding at all? The usual reason to use base-10 is to quickly get an idea of the magnitude of a number relative to things we are familiar with and do some simple arithmetical manipulations on it. Both of these are pointless for Graham's number. Relative to familiar things like billions and trillions it's quite a ways of the chart, and adding, subtracting, or even raising to powers of such makes relatively no difference.
Besides which, in this case it isn't really pointless, it's impossible. Jokes about collapsing into black holes aside, there aren't enough bits of information in the universe to encode the decimal representation of Graham's number. There aren't enough bits of information to encode the number of digits of that. Not enough even to encode the number of digits of the number of digits. Interestingly, there also aren't enough bits to encode the number of times you'll have to repeat taking the base-10 logarithm to get back to a universal scale.
Which goes to show that not only your mind, but no entity in the universe can accomplish the feat of representing an arbitrary number in decimal notation, mathematician or otherwise. And what is the point, really? G is a perfectly good symbol, and so is g_64. Usefulness is important, not imagining a string of balls. For that matter, I bet you've been perfectly content to use Pi on at least a few occasions, even though in terms of representability in decimal, it is infinitely worse than Graham's number.
(|>) :: a -> (a->b) -> b
(|>) x f = f x
infixl 0 |>
There infixl 0 means infix operator with left associativity and 0 precedence.Then you can use all sorts of expressions inbetween:
(5 + 3 |> show) ++ " times" |> putStrLn
Also, tying this back to one of the article's ideas, this piping-like syntax for doing things really manages to take away the emphasis from the function and put it back on the data. It isn't all about functions after all!Why is that? Well, if you deliberately remove words that are easy to put back into the sentence, it's an easy task not because we humans are incredible at "out of the box" thinking, but because one or two word choices are orders of magnitude more likely than all the rest.
And when it comes to statistical guessing, computers are very good at that. Get a large enough corpus of the English language, and I can assure you that the probability distribution of the missing word, given that it's preceded by "I can't stand all" and followed by "your lies" is overwhelmingly in favor of "of".
Calculating these conditional probabilities is not a very hard task to program at all, though it does require quite some computational power and memory for longer chains.
And anyway, marketing aside it's not really a good explanation at all. It's way too abstract to be of any practical use, completely obvious and revealing no information to someone who has made compilers, and completely opaque and, once again, revealing nothing to someone who hasn't.
That's a shame, really. If it works as advertised it would be a really interesting piece of tech. I don't want to know that it parses C# and then converts that tree to one for Java. How else would you do it? On the other hand, how exactly does the mapping from .NET classes to Java ones work? Does the converter also handle coding style and not just syntax and semantics? More importantly, how would you go about doing that?
Overall, I'm not terribly impressed with their transparency.
(foldl * 1 '(1 2 3))
(* 1 (foldl * 1 '(2 3))
(* 1 (* 2 (foldl * 1 '(3))))
(* 1 (* 2 (* 3 (foldl 1 '()))))
(* 1 (* 2 (* 3 1)))
...
6
Basically, the calls to * start nesting into each other, so the one that actually gets evaluated first is the rightmost one.What would actually be foldl is this:
(define (foldl fn accum lst)
(if (null? lst)
accum
(foldl (fn accum (car lst)) (cdr lst))
)
)
Now if you expand this (dropping the tail recursion): (foldl * 1 '(1 2 3))
(foldl * 1 '(2 3))
(foldl * 2 '(3))
(foldl * 6 '())
6
And even though you think that such a tiny thing can't be a good implementations, it actually is super efficient. The tail recursion is automatically optimized for you (and you can assume that for any functional language - it's a very crucial optimization for this style of code, after all). That's what the core of it will be in an actual implementation, though with added error handling, type checking and so on.P.S. unlike haskell, in Racket you don't really need to fold the basic operators, they take variable arguments, so you can just:
(apply * (list 1 2 3))
in order to get it to run on a list.
One caveat is the merging of the drops sometimes looks quite unnatural, but I'm not sure there's any simple way to represent that as just a couple of textures and a transformation, as real drops would have attractive forces on a molecular level pulling them towards one another once they're bridged, deforming pretty unevenly.