Why Concatenative Programming Matters (2012)
- Also, row polymorphism makes the definition of a complete concatenative system much cleaner and smaller; you can get away with only two stack combinators (see http://tunes.org/~iepos/joy.html), and it’s possible to give a type to the Y combinator (∀A B.
- Just curious: is there a fundamental reason why you can't use lambda's and variables in a concatenative language?For example, the 'function' \x could pop the top value of the stack, and bind it to the name x for the remainder of the expression.
- One problem with concatenative languages and point free style is, i think, that named variables are some kind of documentation.With a concatenative lanuguage, you need to know (or document in an informal comment) what inputs and outputs a function has.
How many registers does an x86-64 CPU have?
- I will count registers that aren’t directly addressable, like MSRs that can only be accessed through RDMSR.
- FS and GS are retained as special cases, but no longer use the segment descriptor tables: instead, they access base addresses that are stored in the FSBASE and GSBASE model-specific registers5.
- That pipeline left a bit of cruft towards the end thanks to quoted variants, so I count the actual number at 400 architectural MSRs. That’s a lot more reasonable than 6096!
- The OSDev Wiki has collection of helpful pages on various x86-64 registers, including a great page on the behavior of the segment base MSRs. Modern Intel CPUs use integrated APICs as part of their SMT implementation.
- I didn’t count them because (1) they’re memory mapped, and thus behave more like mapped registers from an arbitrary piece of hardware than CPU registers, and (2) I’m not sure whether AMD uses the same mechanism/implementation.
GridSearchCV or RandomSearchCV?
- Hyperparameter tuning is a powerful tool to enhance your supervised learning models— improving accuracy, precision, and other important metrics by searching the optimal model parameters based on different scoring methods.
- GridSearchCV implements the most obvious way of finding an optimal value for anything — it simply tries all the possible values (that you pass) one at a time and returns which one yielded the best model results, based on the scoring that you want, such as accuracy on the test set.
- The main difference between the pratical implementation of the two methods is that we can use n_iter to specify how many parameter values we want to sample and test.
- There is an obvious trade-off between n_iter and the running time, but (depending on how many possible values you are passing) it is recommended to set n_iter to at least 100 so we can have a higher confidence in the results of the algorithm.
Reverse engineering RAM storage in early Texas Instruments calculator chips
- The problem with dynamic RAM is that the charge leaks away after a few milliseconds, so the values need to be constantly refreshed by reading the data, amplifying the voltages, and storing the values back in the capacitors.5 Texas Instruments developed a new dynamic RAM circuit for the TMS1000 to avoid the complexity of an external refresh circuit.
- The diagram below zooms in on the TMS1000 die photo, showing the 16×16 grid of RAM storage cells.
- The TMS1000 refresh circuit is driven by two clock signals, clock phase 1 (Φ1) and clock phase 5 (Φ5).7 Activating clock phase 5 turns on Q3 and allows the bit to flow to point C, the gate of transistor Q1.
- It's unclear why Texas Instruments continued using inferior metal-gate PMOS circuitry for several years; perhaps calculators didn't need the improved performance so it wasn't cost-effective to switch.
The Cult of Posits
- We make two observations from this plot: First, posits distribute decimal accuracy symmetrically across representations, while floating points fail to deliver at larger numbers, which are ignored in favor of NaN.
- As part of our cultist duties, we compare the accuracy of 32-bit floating point and posit representation by comparing their accuracy under a variety of benchmarks.
- In each benchmark, we express real number calculations in terms of operations over 64-bit doubles.
- With our deepest apologies to Gustafson, we compute these errors on a linear scale, rather than a logarithmic one, and use these as metrics to compare the accuracy of the two representations.
- Although this is an approximation, since no finite representation has perfect accuracy, we assume that the accumulated error in double benchmarks will be truncated or rounded off when comparing with the less precise 32-bit representations.
1.5 is the midpoint between 0 and infinity in Ruby
- To explain these values, we first have to understand how IEEE 754 floating-point numbers work.
- If you don’t know the basics about how floating-point numbers are represented in memory, there are plenty of resources on the internet, here’s one.
- It reads the C double type of the Ruby float endpoints as 64-bit integers (int64_t)1.
- It’s because the more significant bits are always in a more significant position (than the bits to the right of it) in floating-point numbers.
- Once this is true, we can see why binary search works using this technique.
- Ruby’s binary search in a range uses a clever technique to perform binary search when the endpoints are doubles while maintaining a worst-case runtime of O(n log n).
- In fact, this technique isn’t specific to Ruby and can be used in any language that uses IEEE 754 floating-point numbers.