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