1
$\begingroup$

This is not exactly a question but rather a suggestion for a design which I think would greatly improve Mathematica. Before I put this to Wolfram Research I would like to see what other people think about it. Since these days Wolfram is hosting many language design and consistency meeting, I think these might be good times to suggest language improvement ideas.

It is a suggestion for deeper integration of Position inside the pattern-matcher. Currently if you look at the "guide/RulesAndPatterns" page, Position is classified as a Pattern Matching Function like Cases rather than a Pattern Construct Wrapper like Repeated,Except,Longest,....

Its current syntax, Position[expr,pattern,levelspec,n] is geared towards parsing the expr looking for pattern at a specified level levelspec for some number of matches n. It works independently from what is happening in its surrounding. This creates a limitation like if looking for the position of a subPattern which matches in expr while matching a pattern, the only way to achieve this currently is by invoking the pattern-matcher twice.

  • Firstly when the main pattern is matched in expr to get the position of the parts in expr matching the pattern.
  • Secondly when subPattern are matched in parts to get the position of subParts in parts matching the subPattern. But the subPattern could exist in multiple position so tagging is needed to refer to the correct subPart.

See: Can someone please explain the code from another question (Answer by Leonid Shifrin)

One stupid question I asked earlier also highlight this fact.

See: Learning to work with core pattern only (Closed)

Given a data like data = {2,{4,2,3},5,{7,3},{},4,1}. One way to differentiate the outer List from the inner List for the pattern-matcher is to tag it with another Head.

List @@ ((tag @@ data) //. tag[x___, _Integer, y___] :> tag[x, y])

Because currently the pattern-matcher is blind in the sense that it has no awareness of its Position when it is crawling the expression to match pattern.

Admittedly since the expression tree is opened down to Leaves. The pattern-matcher still has awareness of the Depth of the currently reached subExpr even though it can't look up to see the Position of subExpr within the expr. So this problem could be solved by

data//.{t:{x___,_Integer,y___}/;Depth[t]==3:>{x,y}}

without the need for tagging. Another way could be to forcefully change the expression by

data={2,{4,2,3},5,{7,3},{},4,1}
Do[
Print[data=data/.{(t:{x___,_Integer,y___}/;(Echo[Position[data,t],"position"]=={{}})):>{x,y}}],
{k,5}]

But this is still not a "natural" way.

Rather than having a whole suite of functions, like Position[expr, pattern] or SubPosition[expr, pattern, subPattern], it would be a nicer interface to make Position[] a pattern wrapper rather than a pattern matching function.

Position should be a pattern wrapper that tells the pattern-matcher that the name in Pattern[name, ...] wherever referred as Position[name] points to the (matched) object's location rather than the (matched) object itself.

So the above should be solved like:

data//.{t:{x___,_Integer,y___}/;Position[t]=={}:>{x,y}}

and old functionality of Position like

Position[data,{_,_}]

could be replaced by

Cases[data,t:{_,_}:>Position[t]].

With this new wrapper behavior of Position, one could solve the SubPosition problem by simply:

Cases[expr,pattern:>Position[subPattern],\[Infinity]].

Do you think this is a good way to improve (or rather expose) the positional awareness of the pattern-matcher?

Note: Position could be kept as it is for backward compatibility but the new behavior could be linked to a new symbol, say Location or Pointer.

$\endgroup$

closed as primarily opinion-based by Daniel Lichtblau, MarcoB, m_goldberg, LCarvalho, Coolwater Mar 18 at 13:02

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    $\begingroup$ "Note: Position could be kept as it is for compatibility but the new behavior could be linked to a new symbol, say Location or Pointer." So this is an entirely new feature and not at all related to Position or to what Position is supposed to do... $\endgroup$ – Henrik Schumacher Mar 16 at 11:52
  • $\begingroup$ @HenrikSchumacher I would rather want the Position to have the new behavior and completely scrap the current one. Since the new behavior can do the work of the current one but the current one cannot do the work of this new behavior. But I highly doubt it could be done without breaking a lot of code since Position is an elementary function which was introduced back in version 1.0 $\endgroup$ – user13892 Mar 16 at 12:00
  • 1
    $\begingroup$ "But I highly doubt it could be done without breaking a lot of code since Position is an elementary function" That's also what I thought. This is why I believe (and hope!) that this inquiry will be ignored by WRI... $\endgroup$ – Henrik Schumacher Mar 16 at 12:11
  • 3
    $\begingroup$ Why not make up your own function (call it Location or Subposition or something) that implements your desired functionality? This way everyone can see how useful it would be. $\endgroup$ – bill s Mar 16 at 13:06
  • 2
    $\begingroup$ To temper things a bit, maybe consider writing an example implementation of your idea, and maybe try submitting it to the Function Repository? (That being said, I don't see here a question that is suitable for SE's format, but will defer closing decisions to other people.) $\endgroup$ – J. M. is away Mar 16 at 14:25