Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Possible iteration/looping syntax in future Harlowe

Something I've finally taken to serious prototyping recently is some iteration/looping syntax for a more distant Harlowe release. As you may know, I've been steering Harlowe in an FP direction, avoiding imperative forms as much as possible (such that various data structure methods are named for declarative adjectives rather than verbs - (shuffled:), (sorted:) etc.). In that vein, the basic looping constructs I'm providing to Harlowe currently look like this:

* (converted:) is a generalised form of the aforementioned (shuffled:), (sorted:) macros. It accepts multiple values to convert and express as an array, but also accepts a transformer statement, which looks something like "each _data to _data + 1" or "each _itemname to "This item is: " + _itemname". The statement describes what to do to each of the values to make the new array. Some examples:
(converted: each _person to _person + (datamap: 'status', 'poisoned'), ...$people) 
copies every element in the $people array (which I assume contains datamaps of people), but with their 'status' changed to 'poisoned'.

(converted: each _num to (random:0,10), ...(range:1,10)) 
creates an array of 10 random single-digit numbers.

* (filtered:) creates a smaller array from several values, by excluding those which don't match a specific clause statement. Clause statements look like "each _person where _person's HP > 0" or "each _name where $hostageName is not _name". Some examples:
(filtered: each _person where _person's status is 'poisoned', ...$people)
produces an array of the $people whose status is poisoned.

(filtered: each _person where (either:1,2) is 2, ...$people)
produces a random subarray of $people
I'm contemplating renaming this to (find-all:), and inverting the clause from exclusion to inclusion, on the basis that people understand "searching" better than "filtering".

* (combined:) is one that I'm a bit less sure of. It's like (converted:), except you provide a two-value transformer statement which resembles "each _total, _item to _total + _item's price" or "each _currentBiggest, _item to (max: _currentBiggest, _item)". The first value, the "total", equals the previous iteration's value (or the first value, at the start) and the next one is te current passed value (or the second value, at the start), and you specify how to combine each value with the total. Some examples:
(combined: each _text, _person to _text + "Name: " + _person's name + "; Age: " + _person's age + "<br>", ...$people)
Produces a text string listing each person's name and age. You could perhaps think of this as the equivalent of a for-print loop in an imperative language.
The reason I'm unsure about this one is that the placement of the "each" keyword kind of doesn't work here (really, it should read more like "each _item, with _total, to _total + _item's price") and also by the fact that this requires some inductive thinking to properly understand (the idea of expressing a loop in terms of what a single iteration does, relative to its previous iteration) which may be a cognitive load too weighty to bear.

All three of these are based off existing Javascript methods,, Array.prototype.filter() and Array.prototype.reduce().

Any thoughts on these are welcome.


  • I like theses ideas. They'll cut down on the amount of javascript that I need to use. I have a few thoughts.

    You said that converted is a generalised version of sorted and shuffled. To me that implies that sorted and shuffled could be implemented using just converted. I'm not seeing how you could do that. Or am I just misreading you?

    Using Combined there isn't any way to set the initial value of the result (_text in your example). I assume it defaults to an empty value (0 or "" depending on the contents of the array) but it'd be nice to be able to override that.

    Will it be possible to give sorted a comparison function in order to override the default sort order?

    While I'm on the subject of sorted, is there a reason why it only works with strings? It's strange that shuffled will work with numbers, but sorted won't.
Sign In or Register to comment.