Last active
September 7, 2024 12:48
-
-
Save jbunke/60d7b7ba9779f8a44e96f2735ddd460e to your computer and use it in GitHub Desktop.
Simple prime number checker script in DeltaScript that showcases new language features: `when` statement and lambda expressions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ignore .js file extension - only used so GitHub's JavaScript linter provides decent code highlighting | |
/* | |
This script accepts an integer `to_check` and returns true if and only if it is a prime number. | |
Note the use of a when statement, DeltaScript's answer to switch statements. | |
Cases in when statements take three forms: | |
1. `is` cases compare the control expression against an expression and execute their body if the values are equal | |
2. `passes` cases provide a predicate that the control expression is tested against. | |
For a control variable of type T, predicates are functions of type (T -> bool). | |
Predicates can be expressed as function pointers - ::function_name - or as lambda expressions | |
3. when statements can optionally include a final `otherwise` case, which is a universally true case that always | |
executes its body when reached. | |
Cases in when statements are checked sequentially as written. The control flow drops out of the statement once the body | |
of the first valid case has been executed. | |
*/ | |
(int to_check -> bool) { | |
when (to_check) { | |
// predicate is a lambda expression | |
passes n -> n <= 0 -> { | |
print("Please provide a POSITIVE integer"); | |
return false; | |
} | |
// equivalent to `else if (to_check == 1)` | |
is 1 -> return false; | |
// predicate is a function pointer | |
passes ::even -> return to_check == 2; | |
otherwise -> { | |
int factors = factors(to_check); | |
// #| is the length operator - can be called on collections (lists <>, arrays [], sets {}) and strings | |
bool prime = #|factors == 2; | |
if (!prime) { | |
string assembled = ""; | |
// type declarations in foreach loops are optional, as element type can be inferred from the iterable | |
for (factor in factors) | |
assembled += (assembled == "" ? "" : ", ") + factor; | |
print("[ " + assembled + " ]"); | |
} | |
return prime; | |
} | |
} | |
} | |
even(int n -> bool) -> n % 2 == 0 | |
factors(int n -> int<>) { | |
// Declares an immutable list of integers `factors` and initializes it to an empty list of integers | |
// immutability (`~` or `final`) means that `factors` cannot be reassigned; however the existing list may be modified | |
~ int<> factors = <>; | |
int sq = 1; | |
while (sq * sq < n) | |
sq++; | |
for (int check = sq - (sq * sq == n ? 0 : 1); check > 0; check--) | |
if (n % check == 0) { | |
factors.add(check, 0); | |
// appends the complementary factor if it is != to factor `check` | |
if (n / check != check) | |
factors.add(n / check); | |
} | |
return factors; | |
} |
Script boiled down to core logic:
(int to_check -> bool) {
when (to_check) {
passes n -> n <= 1 -> return false;
passes ::even -> return to_check == 2;
otherwise -> return #|factors(to_check) == 2;
}
}
even(int n -> bool) -> n % 2 == 0
factors(int n -> int<>) {
~ int<> factors = <>;
int sq = 1;
while (sq * sq < n)
sq++;
for (int check = sq - (sq * sq == n ? 0 : 1); check > 0; check--) {
if (n % check == 0) {
factors.add(check, 0);
if (n / check != check)
factors.add(n / check);
}
}
return factors;
}
Additional example
has_area(image img -> bool) -> img.w > 0 && img.h > 0
transparent_tl_pixel(image img -> bool) -> has_area(img) && img.pixel(0, 0).alpha == 0
// ...
tl_pixel_or_bw(image img -> color) {
when (img) {
passes ::transparent_tl_pixel -> return #000000;
passes ::has_area -> return img.pixel(0, 0);
otherwise -> return #ffffff;
}
}
// Yes, DeltaScript supports color hex code literals!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
My main reason for preferring the
when
statement is thatto_check
is omitted from our conditions. All conditions are performing checks on the value of that variable, so it seems redundant to reference it repeatedly.Let me know what you think of
when
in DeltaScript! I'd be curious to know what you think of...when
,is
,passes
,otherwise
) - for example, I opted not to reuseelse
forotherwise
Links: