Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple heads and nested lists and functions? #22

Closed
7fe opened this issue Jul 5, 2017 · 12 comments
Closed

Multiple heads and nested lists and functions? #22

7fe opened this issue Jul 5, 2017 · 12 comments

Comments

@7fe
Copy link

7fe commented Jul 5, 2017

Is there a way to match multiple 1,1+ or 0+ heads(also known as variable type/instance of depending on the implementation or first value in a list)? For example let's say I have the following array of JavaScript instances where Number and String could be any type. There is the left and right side of the .. operator. The left side defines the name of the the pattern and the right is the instanceof object(with _caveats).

    [1,2,"3")] // matches [x..Number,y..Number,z..String]
    [1,2] // matches [x..Number,y..Number,z...String]
    [1,2,"3","4"] // matches [x..Number,y..Number,z...String]

In addition what about nested patterns of functions? Doing so would make JavaScript much more like a LISP.

I'm thinking something like the following in Mathematica which would return True. Remember functions in Mathematica start with are written like the following f[agrs] instead of f(args) and arrays are written like {1,2}.

MatchQ[f[1,{"List",1,2}], f[x_,{"List",y__},z___]]

If you are familiar with LISP the following is a basic example.

(setf (readtable-case *readtable*) :invert)
(load 'init.lisp)
(compile-mma)
(load-mma)
(|ReplaceAll| '(f 2 2) '(|Rule| (|Pattern| a (|BlankSequence|)) (f1 a) ) )
 > (F1 ((F1 F) (F1 2) (F1 2)))
(elt '(F1 ((F1 F) (F1 2) (F1 2))))
(|ReplaceAll| '(f 2) '(|Rule| (f (|Pattern| a (|Blank|))) (f1 a) ) )
 > (f1 a)
(|ReplaceAll| '(f a b) '(|Rule| (|Pattern| a (|Blank|))) (f 1 2) )))
> (f a b)

In Mathematica the function name you are trying to match exists before the _ while the variable name exists after the underscore.
Adopting how Mathematica does it it except using the ...

f(x..,["List",y...],z...])

Basically in LISP you can match both functions and lists which are nested. Adapting more examples give me a minute.

let length = vector => match (vector) {
    { x : x.. , y : y.. , z: z.. }: Math.sqrt(x ** 2 + y ** 2 + z ** 2),
    { x: x.. , y : y.. }:   Math.sqrt(x ** 2 + y ** 2),
    [v...] :      [v].length,                   // supports 0 or more elements
    else: {
        throw new Error("Unknown vector type");
    }
}

match (arr) {
    []: /* match an empty array */,
    [x...]: /* match array of any size including 0 */,
    [x..]: /* match an array of length 1, bind its first element as x */,
    [x]: /* match an array with the first variable an actual x */,
    [x..]: /* match an array of at least length 1, bind its first element as x */,
    [ { x: 0, y: 0}, ... ]: /* match an array with the 2d origin as the first element */
}

match (val) {
    1: /* match the Number value 1 */,
    "hello": /* match the String value "hello" */,
}

match (val) {
    r..someRegExp: /* val & r matches the regexp */,
    a..Array: /* val & a is an instance of an array */,
    c..CustomType: /* val & c is an instance (or something) of CustomType */,
    p..PointInterface: /* val & p perhaps a tagged union of some sort */
}

let isVerbose = config => match (config) {
    {output: {verbose: true }}: true,
    else: false
}

values that can get reevaluated can get tricky.

let obj = {
    get x() { /* calculate many things */ }
}
match (obj.x) {
    //...
    else: obj.x // recalculates.
}

match (obj.x) {
    // ...
    x..: x // the result of evaluluating obj.x is bound as x and returned
}

@7fe 7fe changed the title Multiple head's? Multiple heads? Jul 5, 2017
@littledan
Copy link
Member

I don't quite understand. What does the Mathematica code do?

@7fe 7fe changed the title Multiple heads? Multiple heads and nested lists and functions? Jul 5, 2017
@littledan
Copy link
Member

What does it mean to match a function? In your JS example, what do the tildes mean?

@7fe
Copy link
Author

7fe commented Jul 5, 2017

@littledan Matching a functions is more unique to Lisp and Mathematica. I have used ... in place of the underscore in Mathematica. Here is an example in Mathematica. I'm going to try and write up some more examples.

f[a] + f[b] /. f[x_] -> x^2
a^2 + b^2`

http://reference.wolfram.com/language/tutorial/Introduction-Patterns.html.en

@ljharb
Copy link
Member

ljharb commented Jul 5, 2017

How can a function be matched if not by identity? Its name and length are all you can reliably know about it.

@7fe
Copy link
Author

7fe commented Jul 5, 2017

@ljharb do you mean how can they be matched internally or what would the syntax be?

@ljharb
Copy link
Member

ljharb commented Jul 5, 2017

Internally. There's no other meaningful information available (anything that's newly matchable constitutes new exposure of information about a function, and that could violate security concerns)

@7fe
Copy link
Author

7fe commented Jul 5, 2017

@ljharb if you do function.toString() you often get the entire functions body depending on the implementation.
This is just one step further along you to pattern match such.

@ljharb
Copy link
Member

ljharb commented Jul 5, 2017

Correct, but that's not something that we should be matching on.

@7fe
Copy link
Author

7fe commented Jul 5, 2017

@ljharb Pattern matching truly becomes useful when the language is more like LISP which I guess is my opinion.

@bterlson
Copy link
Member

bterlson commented Jul 5, 2017

I don't see how we can support pattern matching on functions. We'd need a proposal for multi-methods or similar which is out of scope for this proposal (but should be considered).

I still don't understand what "heads" means above?

@7fe
Copy link
Author

7fe commented Jul 5, 2017

@bterlson If we are ignoring matching pattern matching functions then Heads can bascically be regarded as the variables instanceof value(with caveats). In haskell it is the first value of a list but that isn't particularly useful and would be covered easily by the implementation above like so [first..,rest...]

@7fe 7fe closed this as completed Jul 8, 2017
@7fe 7fe reopened this Jan 23, 2021
@dustbort
Copy link

dustbort commented Feb 8, 2021

May I ask why this was reopened after 3 years? Honestly, I reread OP several times and I don't understand the issue. Are you essentially asking for active patterns? If so, active patterns don't make sense without tagged union types. If you are asking about pattern matching, there is already this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants