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

Named arguments #65

Closed
FlorianRappl opened this issue Aug 6, 2016 · 2 comments
Closed

Named arguments #65

FlorianRappl opened this issue Aug 6, 2016 · 2 comments

Comments

@FlorianRappl
Copy link
Owner

This is the natural companion of #57. However, I would also go one step further. The tricky thing here is that the name of arguments has to be resolved during runtime. Currently, this is very hard / impossible. Essentially, we have two cases:

  1. Either a function has been declared already in MAGES. Here we may use some kind of meta data / reflection on the function's wrapper (it's a local function).
  2. Or the function is a native one. This one is tricky as we only see the object[] type as arguments (with the potential name args which is kind of useless).

Building upon this we see that the named arguments are quite tricky to handle. There is, however, some hope...

Let's say we restrict named arguments to optional parameters. This way we can essentially say "we restrict named arguments to the first case". Now we are reduced to the simple case and we may solve it by providing a special kind of structure for resolving arguments.

@FlorianRappl
Copy link
Owner Author

The key question that delays this slightly is that the syntax of specifying optional arguments is not yet settled.

In most C-like languages the syntax would be similar to name: value, however, this is ambiguous due to the range definition (start:end).

Also the described way does not play nicely with piping, e.g., instead of foo(a: 3) one cannot simply write a:3 | foo (see previously mentioned problem).

I therefore propose a special function called optional() which accepts 1 argument given as an object with keys mapping to the argument names.

foo(optional({a: 3})) // works
{ a : 3 } | optional | foo // works

The downside of this approach is that it is quite verbose and that I don't see a possibility of mixing optional with standard parameters, such as

foo(5, optional({ b : 2 })) // does not work
foo(optional({a: 5, b: 2 })) // works

Thus I am not sure if this is the right path.

The only other path I am currently seeing is the introduction of a new symbol to mark optionals. One example:

foo(#a 3) // works
#a 3 | foo // works
foo(5, #b 2 ) // works
foo(#a 5, #b 2) // works

Alternatively - and I think that this may be the best option overall - one comes up with a completely new way of doing this. Instead of introducing a mechanism that works only in certain cases I'd like to introduce this on a functional level:

// assume fab = (a = 3, b) => something
fba = foo | permute("b", "a") // (b,a) => fab(a, b)
fb = foo | permute ("b") // b => fab(3, b)

So this function shuffles the input values according to the given names. If a name is not specified either its default name is given or we will always get a function back (currying is then applied by definition).

To have such a function it would also be good to introduce a property to functions called params, which returns an array with all the parameter names.

@FlorianRappl FlorianRappl modified the milestones: 1.4.0, 1.3.0 Oct 5, 2016
@FlorianRappl FlorianRappl modified the milestones: 1.5.0, 1.4.0 Nov 25, 2016
@FlorianRappl
Copy link
Owner Author

This is how it works (final version).

The trivial (identity) works as expected:

fab = (a, b) => a / b;
fab2 = fab | shuffle("a", "b"); //same as shuffle() or shuffle ("a")
fab2(1, 2) // 0.5

We shift the second argument to be the first one:

fab = (a, b) => a / b;
fba = fab | shuffle("b", "a"); //same as shuffle("b")
fba(1, 2) // 2.0

We shift the second argument to be the first one; with optionals still being respected.

fab = (a = 2, b = 4) => a / b;
fba = fab | shuffle("b", "a"); //same as shuffle("b")
fba(1) // 2.0

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

1 participant