Hacker Newsnew | past | comments | ask | show | jobs | submit | prvc's commentslogin

This is neat, but could someone explain the significance or practical (or even theoretical) utility of it?

From the paper:

> Everyone learns many mathematical operations in school: fractions, roots, logarithms, and trigonometric functions (+, −, ×, /, sqrt, sin, cos, log, …), each with its own rules and a dedicated button on a scientific calculator. Higher mathematics reveals that many of these are redundant: for example, trigonometric ones reduce to the complex exponential. How far can this reduction go? We show that it goes all the way: a single operation, eml(x, y), replaces every one of them. A calculator with just two buttons, EML and the digit 1, can compute everything a full scientific calculator does. This is not a mere mathematical trick. Because one repeatable element suffices, mathematical expressions become uniform circuits, much like electronics built from identical transistors, opening new ways to encoding, evaluating, and discovering formulas across scientific computing.


Actually we know this for a long time. The universal approximation theorem states that any arbitrary function can be modelled through a nonlinear basis function so long as capacity is big enough. The practical bit here is knowing how many basis functions can be approximated with a two operators. That’s new!

Read the paper. On the third page is a "Significance statement".

eh, i didnt find that paragraph very helpful. it just restates what it means do decompose an expression into another one only relying on eml, and vaguely gestures at what this could mean, i was hoping for something more specific.

second, please help us laypeople here

It's potentially useful for computer algebra with complex numbers - we might be able to simplify formulas using non-standard methods, but instead via pattern matching. We might use this to represent exact numbers internally, and only produce an inexact result when we later reduce the expression.

Consider it a bit like a "church encoding" for complex numbers. I'll try to demonstrate with an S-expression representation.

---

A small primer if you're not familiar. S-expressions are basically atoms (symbols/numbers etc), pairs, or null.

    S = <symbol>
      | <number>
      | (S . S)      ;; aka pair
      | ()           ;; aka null
    
There's some syntax sugar for right chains of pairs to form lists:

    (a b c)          == (a . (b . (c . ()))   ;; a proper list
    (a b . c)        == (a . (b . c))         ;; an improper list
    (#0=(a b c) #0#) == ((a b c) (a b c))     ;; a list with a repeated sublist using a reference
---

So, we have a function `eml(x, y) and a constant `1`. `x` and `y` are symbols.

Lets say we're going to replace `eml` with an infix operator `.`, and replace the unit 1 with `()`.

    C = <symbol>
      | <number>
      | (C . C)      ;; eml
      | ()           ;; 1
We have basically the same context-free structure - we can encode complex numbers as lists. Let's define ourselves a couple of symbols for use in the examples:

    ($define x (string->symbol "x"))
    ($define y (string->symbol "y"))
And now we can define the `eml` function as an alias for `cons`.

    ($define! eml cons)

    (eml x y)
    ;; Output: (x . y)
We can now write a bunch of functions which construct trees, representing the operations they perform. We use only `eml` or previously defined functions to construct each tree:

    ;; e^x

        ($define! exp     ($lambda (x) (eml x ())))
        
        (exp x)
        ;; Output: (x)
        ;; Note: (x) is syntax sugar for (x . ())

    ;; Euler's number `e`

        ($define! c:e     (exp ()))
        
        c:e          
        ;; Output: (())
        ;; Note: (()) is syntax sugar for (() . ())

    ;; exp(1) - ln(x)

        ($define! e1ml    ($lambda (x) (eml () x)))
        
        (e1ml x) 
        ;; Output: (() . x)

    ;; ln(x)

        ($define! ln      ($lambda (x) (e1ml (exp (e1ml x)))))
        
        (ln x)
        ;; Output: (() (() . x))

    ;; Zero

        ($define! c:0      (ln ()))
        
        c:0
        ;; Output: (() (()))

    ;; -infinity

        ($define! c:-inf   (ln 0))
        
        c:-inf
        ;; Output: (() (() () (())))

    ;; -x
        
        ($define! neg      ($lambda (x) (eml c:-inf (exp x))))

        (neg x)
        ;; Output: ((() (() () (()))) x)
        
    ;; +infinity
    
        ($define! c:+inf   (neg c:-inf))
        
        c:+inf
        ;; Output: (#0=(() (() () (()))) #0#)
        
    ;; 1/x
    
        ($define! recip    ($lambda (x) (exp (eml c:-inf x))))
        
        (recip x)
        ;; Output: (((() (() () (()))) . x))
  
    ;; x - y
    
        ($define! sub      ($lambda (x y) (eml (ln x) (exp y))))
    
        (sub x y)
        ;; Output: ((() (() . x)) y)
    
    ;; x + y
    
        ($define! add      ($lambda (x y) (sub x (neg y))))
    
        (add x y)
        ;; Output: ((() (() . x)) ((() (() () (()))) y))
    
    ;; x * y
    
        ($define! mul      ($lambda (x y) (exp (add (ln x) (exp (neg y))))))
        
        (mul x y)
        ;; Output: (((() (() () (() . x))) (#0=(() (() () (()))) ((#0# y)))))
        
    ;; x / y
    
        ($define! div      ($lambda (x y) (exp (sub (ln x) (ln y)))))
        
        (div x y)
        ;; Output: (((() (() () (() . x))) (() (() . y))))
        
    ;; x^y
    
        ($define! pow      ($lambda (x y) (exp (mul x (ln y)))))
  
        (pow x y)
        ;; Output: ((((() (() () (() . x))) (#0=(() (() () (()))) ((#0# (() (() . y))))))))
  
I'll stop there, but we continue for implementing all the trig, pi, etc using the same approach.

So basically, we have a way of constructing trees based on `eml`

Next, we pattern match. For example, to pattern match over addition, extract the `x` and `y` values, we can use:

    ($define! perform-addition
        ($lambda (add-expr)
            ($let ((((() (() . x)) ((() (() () (()))) y)) add-expr))
                (+ x y))))

    ;; Note, + is provided by the language to perform addition of complex numbers

    (perform-addition (add 256 512))
    ;; Output: 768
So we didn't need to actually compute any `exp(x)` or `ln(y)` to perform this addition - we just needed to pattern match over the tree, which in this case the language does for us via deconstructing `$let`.

There's a bit more work involved for a full pattern matcher which will take some arbitrary `expr` and perform the relevant computation. I'm still working on that.

Examples are in the Kernel programming language, tested using klisp[1]

[1]:https://github.com/dbohdan/klisp


The concept of "meat" presupposes the existence of carnivores, so it's hard to see how the realization in the story could ever have been surprising.

Have they announced any price from which to adjust? If not, then it would be unnecessary for them to announce the adjustment.


The Steam Deck is an established product that was first released in February 2022. You may be thinking of the Steam Machine, which indeed does not have public pricing that I'm aware of.


"Disciples", but seemingly without back and forth feedback from the "teacher". Many happy to ride on the coattails of his reputation, though. This particular style might also be attractive to new film-makers because it allows them to dispense with learning the basics of traditional film language.


Apples to oranges.


Should have just quoted what Hooke said... not sure what we're supposed to take away from this.


>The best way to reclaim our digital experiences, though, might be to stick with the likes of TextEdit, software that is unable to do anything except follow our commands.

Man, if he only knew...


This situation persists: for instance, try to write to an external disk formatted with NTFS using the GUI tools alone. Baffling why Apple doesn't simply obtain a license in order to gain this capability. Big unnecessary inconvenience, primarily for their own users.


exFAT to the rescue


Anyone wondering what might have prompted his evident change of attitude after already having engaged in a "correspondence" with Mosley should note that this letter was written during Ralph Schoenman's infamous tenure as Russell's secretary.


An interesting prospective project for a technically minded musician would be would be to find an automated way to "correct" the surviving corpus of Welte-Mignon[1] recordings. They were designed to capture the small nuances of performances (such as dynamics), and a large number of historically important musicians made recorded performances in this medium before the era of sound recording. In my strongly-held opinion, the rolls were marked in an uneven and imprecise way, making direct playback on anything but the original recording apparatus inaccurate. A common trait of modern renderings of these rolls as sound recordings (as found on CD or on Youtube) is an unevenness of tempo and a seeming lack of synchronization of voices (really piano keys). However, the mechanical quirks and imprecision in the recording apparatus must be regular enough to allow for a more accurate version of the performances to be reconstructed, without relying on unduly many aesthetic assumptions.

[1] https://en.wikipedia.org/wiki/Welte-Mignon


I learned about this a few years ago and was delighted to hear some actual performances by Debussy of his own pieces. I was unimpressed by the quality of the recordings, though (via replaying on a restored mechanism) so it's great to get a MIDI version now!

How did the Welte-Mignon actually work? It seems almost miraculous that the dynamics can be captured on a piano roll and replayed successfully. Not perfectly, as you say, but pretty damn close.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: