Words and Buttons is a site of interactive explanations on programming, C, numerical methods, and code readability.
HN commenters like its lexical differential highlighting idea and the "So You Think You Know C?" quiz and book, which illustrate undefined behavior.
> How do we pick up that writing style.
since the discussion here revolves around "intentionally obfuscated c", i'd like to recommend three sources which elucidate what obfuscated c is:
1. this is not how you want to write c. this is very bad news:
#include <stdio.h> #include <stdlib.h> int main() { int *p = (int*)malloc(sizeof(int)); int *q = (int*)realloc(p,sizeof(int)); *p = 1; *q = 2; if (p == q) printf("%d %d\n", *p, *q); } 2. what follows is five trivial questions about c. correct answer to all five is "i don't know". you don't even need to understand why that is, what you want instead is keep it simple. "Origins of J" from 1989 is infinitely more sane and approachable than any of these five:
https://wordsandbuttons.online/so_you_think_you_know_c.html
3. what amazes me is that no single person in this thread yet illuminated us with a staple wisecrack piece of general form "preprocessor is evil". so, let me do it: preprocessor and fancy macros are EVIL, and they are not your friends. if you don't know when to stop producing them, they will turn on you, and will become deadly.
this effect can be described in less sinister language, sunny side up. if you understand at least 30% of untold sorrow which happens below, you are 100% qualified to use preprocessor:
//!\file adios.h //! first things first #define struct union #define if while #define else #define break //!< what a sweetheart #define if(x) …
Thank you, really happy to hear you enjoyed it!
You can find more short little APL games at
https://github.com/jamescprice/131-APL-Games-for-your-Commodore-64-C128-and-SuperPET/tree/main/131%20APL%20Games
It's meant to be a little games book in the spirit of the 1980s books of short little games for the 8bits of the era, and a love letter to APL and the Commodore line. Usually each game brings in a new glyph and you can get a feel for how the language works by looking them over. A work in progress.
Ken Iverson's "Notation as a Tool of Thought" paper/manifesto is a great read and speaks to the philosophy behind APL quite well. He makes a pretty good case for how a programming language without ANY keywords, just symbolic glyphs, is expressive, suggestive, and economic. Classic APL existed as a mathematical notation before it was implemented as a living symbolic maths language, and you can sense that heavy mathematical background in all the crazy glyphs being used.
The wikipedia page on floor and ceiling functions (https://en.wikipedia.org/wiki/Floor_and_ceiling_functions) says "Carl Friedrich Gauss introduced the square bracket notation [x] in his third proof of quadratic reciprocity (1808).[3] This remained the standard[4] in mathematics until Kenneth E. Iverson introduced, in his 1962 book A Programming Language, the names "floor" and "ceiling" and the corresponding notations ⌊x⌋ and ⌈x⌉.[5][6]
The wonderful Words and Buttons site has a nice writeup at…
To beat OpenBLAS is neither suprising nor it's not unheard of, for example D language library Mir for linear algebra did just that many years ago [1]. For C++ and C implementation please check these metaprogramming approaches [2], [3].
What's really surprising is that many modern languages are still depending on OpenBLAS for examples Matlab, Julia, Mojo, etc. But to be fair they probably have their own reasons, right?
[1] Numeric age for D: Mir GLAS is faster than OpenBLAS and Eigen (2016):
http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/glas-gemm-benchmark.html
[2] Vastly outperforming LAPACK with C++ metaprogramming (2018):
https://wordsandbuttons.online/vastly_outperforming_lapack_with_cpp_metaprogramming.html
[3] Outperforming LAPACK with C metaprogramming (2018):
https://wordsandbuttons.online/outperforming_lapack_with_c_metaprogramming.html
I love the concept of lexical differential highlighting [0] (discussed here [1]). It makes reading math so much easier, especially in dense code. However I don't know of any editor that implements a feature like this.
If you paste the following code into the example block in [0] you can see how useful this can be:
while (b - a).abs() > EPSILON { let c = a + (a - b) * f_a / (f_b - f_a); let f_c = J(c); if f_c * f_b == 0.0 { a = b; f_a = f_b; } else { f_a /= 2.0; } b = c; f_b = f_c; } [0]: https://wordsandbuttons.online/lexical_differential_highlighting_instead_of_syntax_highlighting.html
[1]: https://news.ycombinator.com/item?id=20414528
The most intriguing version I've heard of this was also based on the feeling that it's already easy to scan for keywords and structure; they went a different direction, using color to make different things (especially confusable ones) look different: https://wordsandbuttons.online/lexical_differential_highlighting_instead_of_syntax_highlighting.html
I don't feel like I know how/if highlighting helps, so all I can really say is seems interesting.
I think some of the problems commenters are having with the color scheme are because the site has a dark mode and contrast might be worse when it's on. Maybe in that mode text colors meant for a dark background are still getting applied in the white-backgrounded code fragments.
Hm for me interactive visualizations are more illuminating:
https://www.falstad.com/dotproduct/
https://wordsandbuttons.online/interactive_mnemonics_for_dot_and_cross_vector_products.html
In essence then, not as confusing to the beginner who might even know what a dot product 'is' operationally but not what it 'does'.
So level 1 'it's just a normalized dot product', level 2 more immediately intuitive: 'is arrow 1 pointing in the same direction as arrow 2?' or 'how close is arrow 1's direction to arrow 2's direction?'
Now what's left after that is 'Why is it so? Why did we decide on this in embeddings?'