Show HN: The Blots Programming Language
blots-lang.orgMore broadly, a lot of other command line utils for transforming input have such an emphasis on terseness that I sort of bounce off of them. awk and sed and jq are all super powerful tools, but I wanted a tool that had a more balanced trade-off of characters vs. clarity.
Sounds hard but it's quite easy with stack architecture :) Easier than learning JS for sure
i:"%j" parse shell["curl -s https://api.weather.gov/gridpoints/BOU/63,62/forecast"].out
t:i.properties.periods..temperature
o.average:(sum t)/count t
o.minimum:min t
o.maximum:max t
show[o]
Lil doesn't have implicit parsing of .json arguments like Blots- certainly a nice feature for the niche Blots is aimed at. Lil also doesn't have an arithmetic average as a builtin like Blots, but in this case it's easy enough to do without.The biggest difference here is how Lil handles indexing: The ".." in that second line can be read as "for every index"; a wildcard. I can follow the mapping that occurs in Blots' "via" expression, but I find it less clear in this example.
It can also be nice to treat lists-of-objects as proper SQL-like tables:
select number name temperature windSpeed from table i.properties.periods
+--------+-------------------+-------------+---------------+
| number | name | temperature | windSpeed |
+--------+-------------------+-------------+---------------+
| 1 | "This Afternoon" | 54 | "14 mph" |
| 2 | "Tonight" | 46 | "3 to 12 mph" |
| 3 | "Wednesday" | 69 | "5 mph" |
| 4 | "Wednesday Night" | 45 | "3 mph" |
| 5 | "Thursday" | 79 | "5 mph" |
| 6 | "Thursday Night" | 49 | "5 mph" |
| 7 | "Friday" | 83 | "2 to 6 mph" |
| 8 | "Friday Night" | 52 | "6 mph" |
| 9 | "Saturday" | 81 | "3 to 8 mph" |
| 10 | "Saturday Night" | 53 | "3 to 8 mph" |
| 11 | "Sunday" | 81 | "3 to 7 mph" |
| 12 | "Sunday Night" | 54 | "3 to 7 mph" |
| 13 | "Monday" | 77 | "3 to 7 mph" |
| 14 | "Monday Night" | 53 | "3 to 7 mph" |
+--------+-------------------+-------------+---------------+
I hope you continue to tinker and evolve Blots; a personal scripting language guided by the use-cases you encounter naturally can be very rewarding and useful. ~> http get https://api.weather.gov/gridpoints/BOU/63,62/forecast
| from json
| get properties.periods.temperature
| {average: ($in | math avg) minimum: ($in | math min) maximum: ($in | math max)}
╭─────────┬───────╮
│ average │ 66.36 │
│ minimum │ 52 │
│ maximum │ 81 │
╰─────────┴───────╯
~> [1, 2, 3] * 10 // [10, 20, 30] (because [1 * 10 = 10, 2 * 10 = 20, 3 * 10 = 30])
[4, 5, 6] > 3 // true (because [4 > 3 = true, 5 > 3 = true, 6 > 3 = true], so the condition is true for all elements)
I guess most people would have expected that second expression to return [true, true, true]
Is this really more practical to single out booleans like that, compared to having a separate step for ANDing?``` [1, 2, 3] * 10 // [10, 20, 30] [10, 20, 30] + 2 // [12, 22, 32] [4, 5, 6] > 3 // [true, true, true] [1, 2] == [2, 2] // [false, true] ```
In addition, I’ve added both `all` and `any` as built-in functions. These can be used to achieve the same result as the previous broadcasting behavior:
``` [4, 5, 6] > 4 into all // false [4, 5, 6] > 4 into any // true
// alternatively: all([4, 5, 6] > 4) // false any([4, 5, 6] > 4) // true ```
Thanks for the feedback!