Friday, May 31, 2024

Lazy sequences

Lazy sequences are a useful tool in programming.  They represent potentially infinite sequences of data, but only one element at a time.  You could represent the natural numbers as a lazy sequence of 0, 1, 2, 3, ...  The trick is to limit how many of these elements you create and use at a time.  Of course, you could also use lazy evaluation of a finite sequence, like iterating through each element of a list, but only as needed by the program logic

How do you create a lazy sequence?

next(state, iterator)

state is the current state of your sequence.  It might be a list and a pointer to the current element, or it might be the current integer in an infinite series.

iterator is a function that, given the state, produces the current element in sequence and updates the state.  If given the state of 5, an iterator should produce 5 and then update the state to 6.  If given a state like [[`a `b `c `d `e `f `g], 2], the iterator should produce `c and then update the 2 to a 3.  In addition, the iterator function must also report whether it has reached the limit of its function as a boolean (true/false) flag.  This could occur by reaching the end of a list, or by iterating all the way to the highest (or lowest) expressible value of the function.

next is simply a function that applies the iterator function to the state.  Ultimately, next produces an iteration result along with a status indicator.  This indicator should be used by the surrounding program loop to decide whether to continue the lazy iteration or not.

Sunday, May 26, 2024

The reason for the holiday

In 1865, the great national bloodletting finally, fitfully, drew to a close.


Whatever side you retroactively support, whichever cause you retroactively champion, remember that hundreds of thousands of men died fighting for it.

One in thirty Northern men died in the war.
One in twenty Southern men died in the war.

More men died in a single day near Sharpsburg, Maryland, on each side, than the total butcher's bill of twenty years in Afghanistan.

Thursday, May 23, 2024

Particle motion

This is what motion is for a particle.  It's a first order (first derivative) Gaussian wave.  (All images as stolen from the internet.)

Motion is left to right.  The particle is both the center (zero point) of the wave, and the entire wave.



Here it is in 3D.



The important part about a field is the gradient (relative change at any point).  This is what does work.  Work is change.  Gravity and motion are the same thing, so they must share a cause.  Spacetime is the field that describes motion.  Lorentzian gamma shift is caused by the particle's internal gradient, combined with the gradient of the spacetime path.  Two particles with identical velocity (speed and direction) in a level field will have blue and red shifts that exactly cancel out between them.  Notice that there is no blue/red shift at 90 degrees to the direction of motion.

Always remember the zeroth law of physics - everything except energy adds up to nothing.

For some deeper insight into energy, see Hans G. Schantz's paper on standing waves.


Saturday, May 18, 2024

Single word comments

In Listack, I created "sugar words" to improve readability, the downfall of the homoiconic languages.  (Lisp, Joy, Factor, Listack, etc.)

    if: {> 5} then {"Is greater than 5." .println} else {Is not greater than 5." .println} 

In hindsight, this was a mistake.  It complicated the parser and slowed down the interpreter.  In addition, you could make your own sugar words - which could spell disaster if sugar words created in one module interfered with words in another.

As a simpler solution (and simpler is almost always better!), I created the single word comment.

    if: {> 5} #then {"Is greater than 5." .println} #else {Is not greater than 5." .println} 

This form is handled quite simply by the parser, has no effect on the interpreter, and you can't accidentally shadow a real word.  The effect is similar to optional keywords in other languages, but is accomplished more simply.

Friday, May 10, 2024

UFCS and function chaining

Which is more readable?

display_in_columns(count_each(sort(to_lower_case(extract_words(some_long_string_of_words)))))

some_long_string_of_words
    .extract_words
    .to_lower_case
    .sort
    .count_each
    .display_in_columns

Monday, May 6, 2024

Why Uniform Function Call Syntax matters

Uniform Function Call Syntax (UFCS) is a computer language pattern that allows commands/procedures/functions to be called in visually different ways.  Why is this important?  Why should any programmer care?

Readability.

90% of programming time is reading what somebody wrote in the past, not writing new code.
90% of programming is bug fixing and refactoring.

Oh, wait, what is refactoring?  Changing the code to make it more readable.  Not faster.  Not more efficient.  More readable.

UFCS allows code to be more readable.  That's all it does.  That's all it has to do.

Which of these is more readable to you?

                                                                                                 Listack
1 add 2        Swift                    operator / infix style                1 add 2
add 1 2        Haskell                prefix style                               add: 1 2
add(1, 2)      C                         procedure call style                  add(1, 2)
(add 1 2)      LISP                    Lisp style                                 (add: 1 2)
1 2 add        Forth                    method call / postfix style       1 2 .add

These are all valid program snippets from different languages.  They are all readable to varying degrees.  They are all in different styles.  They are all equivalent.

UFCS, especially as implemented in Listack, allows you to use whichever one is more appropriate at the time.  Want to us standard function call?  Do it.  Want to chain together a bunch of functions in a pipeline on a single piece of data?  Do it.

Function chaining example - which is more readable?  They all do the same thing, resulting in 3.  (There are more possible variations.)

1 5 3 .sub .add
(add: 1 (sub: 5 3))
add: 1 sub(5, 3)
add(1, sub(5, 3))
1 add sub(5, 3)
1 (5 sub 3) .add

Listack has the additional advantage that infix operators (+, -, etc.) are not special.  So you can use a simple '+' instead of 'add' when creating your own procedures.

1 + 2     --> 3
"Hello " + "there!"     --> "Hello there!"
myCustomThing1 + myCustomThing2        --> myCustomThing3