Show HN: The Blots Programming Language (blots-lang.org)

55 points by paulrusso ↗ HN
I've been working on this small, slightly weird expression-oriented programming language for a little while now and feel ready to share it with others. I use it pretty often now in my day-to-day and work life, as a scratchpad for doing a bit of quick math or picking some pieces of data out of a JSON payload.

Would really appreciate any feedback about the syntax, docs, features that are glaringly missing, etc. Before anybody mentions it: I know the performance is pretty lousy when dealing with a lot of data. If you can believe it, the runtime is about 100x faster than it used to be! Long term I'd like to switch to a proper bytecode interpreter, but so far performance has been Good Enough for my use cases.

Thanks for taking a look!

10 comments

[ 3.7 ms ] story [ 36.2 ms ] thread
What would you say is a benefit of using this over using jq?
Super cool! I’ve always wanted to make my own lil language and I’ve always been too intimidated to try.
nowadays it is somewhat easier to make your own programming language, than it was 10 to 20 or 30 years ago, because there are a lot of resources such as tutorials and open source projects available on the internet, in both text and video formats, to learn from. there are also many online forums where you can ask questions and get answers and advice.
Start with writing a custom cpu emulator -> machine code -> assembler -> compiler

Sounds hard but it's quite easy with stack architecture :) Easier than learning JS for sure

I’m curious, what was the hardest part about making Blots? And what was the most fun part?
Blot on the landscape was a brilliant subversive comedy British TV series from the 80s.
For contrast, here's how I'd handle the example given on the front page in Lil[0]:

    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.

[0] http://beyondloom.com/tools/trylil.html

This is the sort of thing I use Nushell for, brilliant data focus shell!
From the readme:

  [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?
Hey! I've received this feedback from a few different people, and I agree with it. The latest version of Blots (0.8.0) changes the behavior of broadcast comparisons. Now, comparisons are applied to each element in the list, producing a new list of booleans. As you pointed out, this better matches the broadcasting behavior of arithmetic operators:

``` [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!