This answer assumes C#, I do not believe (explained below) that this can be answered in a way that applies to numerous languages.
As we have discovered, this is not an easy question to answer... This answer is based on my miserable commentary from another question about C# and Lambdas. The reason I do all this talking to start with is because we have half a dozen questions about statically typed languages, and they have achieved almost nothing, so I'm stating (and assuming) some general (language specific) rules that we could use before trying to answer this questions which should be answerable by understanding the general rules about the language (though we can add more specific rules if we wanted). I shall probably write a meta question up about these 'general rules' in due course.
Your code should be self-contained and well defined
We can define 'well defined' on a per language basis. If we want enforcable rules, we have to do this, because it is well recognise that we don't require code that compiles on it's own, so we need per-language rules to decide what is or is not well defined. For example, taking C# as an example (widly applicable to Java): we define 'well defined' code as code which compiles under one of the trivially identifiable and applicable situations below:
As a complete program
That is, something you can stuff in a file, called csc mycode.cs
on it and get csc mycode.exe
out.
As a member of a class
Example E
Stuff your code into the boilerplate below. You may not define your own boilerplate in your answer, that would be silly.
/*usings here perhaps?*/
class LONGCLASSNAMETHATWONTCLASH
{
/*submission here*/
/*calling code (in a method or w/e)*/
}
As a locally defined function
Example F
More C&Ping...
class ANOTHERLONGCLASSNAMETHATWONTCLASH
{
void LONGMETHODNAMETHATWONTCLASH()
{
/*submission code*/
/* calling code */
}
}
As an anonymous well-typed method
Example H
And from Martin's prompting, maybe we can even stretch to not requiring you to put brackets around your well typed lambdas:
// taken to be in a method
var result = (/*submission here*/)(/*arguments*/);
Now to answer the question at hand...
.... Assuming all of the above (which we have no consensus on at this time), we have to find a way to fit 2 named function definitions into one of these boilerplates above. This makes everything very simple, your best option is member functions (or local functions (C# 7)):
typename f(typename n)=>g(n)+doSomethingMore;
typename g(typename n)=>doSomethingWithInput;
I'm not sure what the shortest Java code would be under similar rules.
If we agreed to add a surprise semi-colon in the (example) boilerplates, we could often spare ourselves a byte, but would invalidate many answers also. Alternatively, we could be generous and allow either with or without a semi-colon (they should't change the meaning ,but C# can be picky about these things (and given the small space or allowed boilerplate, you could argue it doesn't matter)).
Counter Discussion
Indeed, one could argue that writing one method has a much lower overhead than writing two (and this is what the question is saying). That could be a separate decision, but until we have general rules for languages, it is just going to add to the confusion and misery that is ruling (in particular) on statically typed languages (that is, if you are of a similar miserable school of thought to that I am).
Some sort of delimiter would absolutely be necessary (i.e. you can't just say it is two functions, the code needs to make this clear, and the code that does so must be included in the byte count).
f=n->doSomethingWithInput
is valid and complete syntax to cause a named functionf
to be defined in your language then this is fine. Otherwise, it's not. \$\endgroup\$s=>s.Length;
which compiles down to aFunc<string, int>
. Are you saying thats=>..
is fine on its own or I should be writingFunc...s=>...
? \$\endgroup\$s=>s.Length
is fine (I don't think you'd need the semicolon, because it's not even part of the expression). The problem only arises when your function needs a name, so that it can be called by itself or another function. \$\endgroup\$f=
is for (and which is also required for recursive calls). But does this mean we can leave out theFunction<...>
part for both methods like in (1) or (4), or should we add it like in (2) or (3)? (Also my bad for both calling them anonymous, when the second obviously is not..) \$\endgroup\$f@n_:=3n;f@#+1&
is a single expression which leavesf
defined and then evaluates to an unnamed function which computes3n+1
. However, in Java, a construct like this would not be a single expression but a combination of a full statement and an unnamed expression. \$\endgroup\$g=n->f(n)+doSomethingMore
andf=n->doSomethingWithInput
instead. A functiong
which calls functionf
. I'll add this option to the question, because it indeed seems like the one that is the best to understand. \$\endgroup\$s=>DoSomething
with two you'd dof=s=>g()+DoSomething
, in the second case would you have to include the trailing semicolon asf=s=>g()+DoSomething;
? \$\endgroup\$s=>s.Length
is not fine (at least in my book) because it has no meaning in C# out of context, and (crucially) the meaning depends on the context, and the context is not trivially determinable (i.e. you can't write two more strings which you plaster on either side of an 'untyped lambda expression' to give it meaning). \$\endgroup\$