I understand the point of not adding more syntax and I agree with it, but I think this is such big missing feature in Pharo and that it could be provided by default in the image as an API instead of a syntax sugar. https://github.com/dvmason/Pharo-Functional has both approaches ��� syntax and API ��� and I really like the `chain` strategy ��� I had implemented one of my own some years ago based on a suggestion made here on this list.

So the original example code would be like this:

json chain at: ���tree';
�� �� �� �� select: [ :e | ((e at: 'type') = 'blob���)];
�� �� �� �� collect: [:e | Path from: (e at: 'path���)];
�� �� �� �� select: [ :p | p segments last
�� �� �� �� �� �� �� �� in: [ :name | (name endsWith: '.md') | (name endsWith: '.mic') ] ]

The chain stores the last returned object to be used as the receiver of the next message send. You can do it using a DNU, but maybe there is a more optimized way of doing it, and also using DNU do not work with messages present on the chain base class (Object), maybe tehre is a way to circumvent that also.

Regards,
Vitor



On Wed, Jan 26, 2022 at 11:33 AM Richard Sargent <richard.sargent@gemtalksystems.com> wrote:
On Wed, Jan 26, 2022 at 4:40 AM Sven Van Caekenberghe <sven@stfx.eu> wrote:
Hi Kaspar,

I found the initial example actually reasonable readable.

However, I would simplify it as follows:

(json at: #tree)
�� select: [ :each |
�� �� ((each at: #type) = #blob)
�� �� �� and: [ #(md mic) includes: (Path from: (each at: #path)) extension ] ].

I would personally not try to extend the Smalltalk syntax. The cost is not worth the gain.

Tools could be written to help in dealing with deeply nested structures (JSON/XML), they could form their own DSL at a higher level.

For a limited example, NeoJSONObject uses the DNU trick to support unary accessors:

�� json at: #tree

can be written as

�� json tree

and has a path accessor:

�� json atPath: #(tree field name)

it also behaves like JavaScript objects in that missing keys are nil. It is not that all this is good or better, it is just handy in some cases. Your code would then be even simpler (less parenthesis):

json tree select: [ :each |
�� (each type = #blob)
�� �� and: [ #(md mic) includes: (Path from: each path) extension ] ].

That is the kind of expressiveness I was looking for!



Sven

> On 26 Jan 2022, at 10:19, Kasper Osterbye <kasper.osterbye@gmail.com> wrote:
>
> Cheers all
>
> I have noticed that I often ends up with quite a number of nested expressions, for example:
>
> (((json at: 'tree')
>�� �� �� ��select: [ :e | (e at: 'type') = ���blob' ])
>�� �� �� �� �� �� �� ��collect: [:e | Path from: (e at: 'path')])
>�� �� �� �� �� �� �� �� �� �� �� ��select: [ :p | p segments last
>�� �� �� �� �� �� �� �� �� �� �� �� �� �� �� ��in: [ :name | (name endsWith: '.md') | (name endsWith: '.mic') ] ]
>
> What kind of proposals (if any) have been for a different syntax which could give a more streamlined syntax?
>
> My own thinking has been around an alternative to the cascade semicolon. What symbol to use does not matter for me, but something like
> json at: ���tree' ��
>�� �� �� ��select: [ :e | ((e at: 'type') = 'blob���)]��
>�� �� �� ��collect: [:e | Path from: (e at: 'path���)]��
>�� �� �� ��select: [ :p | p segments last
>�� �� �� �� �� �� �� ��in: [ :name | (name endsWith: '.md') | (name endsWith: '.mic') ] ]
>
> Basically, a send the right hand expression to the result of the left hand expression.
>
> Has anyone ever tried this, or is it just one of the many small annoyances best left alone?
>
> Best,
>
> Kasper