cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar

Keyword arguments for functions

I would love if in User Defined funcitons we could use keyword arguments in the calls so I can do

Names default to here(1);
f = function({x, y=2, z=3}, 
	show(x, y, z);
);
print("What I'd like to do");
f(1, z=2);
//I want it to be 1, 2, 2

//instead of having to do 
f = function({x, kwargs={}},
	{DEFAULT LOCAL}, 
	// optional
	y = 2;
	z = 3;
	evallist(kwargs);
	show(x, y, z);	
);
print("Using List");
f(1, {z=2});

Someone mentioned it here, but it was 8 years ago, so figured I'd bring it up again.  

14 Comments
gzmorgan0
Super User (Alumni)

@vince_faller 

 

Cool example. Thanks for Sharing. Typo correction

show(f(2, {y=14})); // 36 not 33

 

hogi
Level XI

How are the standard Jmp functions defined,

- such that close accepts an supplementary argument noSave.

- such that add column accepts the expression Formula(...) at any position within (...)

dt << New Column( "X", Formula( row() ) );

Instead of 

f(2, {y=14})

could 

f(2, y(14))

be the way how it should look like?

Craige_Hales
Super User

The internal functions are built in C++, not JSL. The user functions (in JSL) are interpreted by other C++ code that chooses how to  turn arguments into parameters (where the arguments to a function are the external values passed in and the function's parameters are the internal variable names that refer to the values.)

A function like sin(A), written in C++, looks something like

ExpressionPointer sin( ExpressionPointer E) {
   double value = evaluateExpression( E );
   double answer = sin( value );
   return makeExpression( answer );
}

The expr() function in JSL, where the function just returns its argument without studying it, looks something like

ExpressionPointer expr( ExpressionPtr E ) {
   return E;
}

That seem useless at first glance, but it allows the assignment operator to evaluate the right-hand-side of

ex = expr( a + b );

and store an expression tree into ex rather than the result of a+b. A more interesting example is the head(a+b) operator.

ExpressionPointer head( ExpressionPointer E ) {
   return MakeExpression( E->child );
}

That's a crude approximation of the idea: an expression tree for a+b has a root, +, which has two children, a and b.  E->child is getting the root, +, and returning that as an expression with no children.

The JMP developers made a decision to hide that complexity in the JSL user written functions to make the 99% use cases easy to write. Most of the languages I'm familiar with don't have expressions that can be manipulated (Snobol does, sort of, and that explains JMP's patmatch() function...) Using a list is a reasonable approach to sending an expression to a function; the list is evaluated...to the same list. The function is working on a copy of the list.

 

Status changed to: Acknowledged