I am modelling a programming language for fun, and the syntax is heavily influenced by Scala - specifically function definitions.

I have encountered a design problem because my language does not differentiate between functions defined via the def syntax (class methods) and anonymous functions assigned to values (created using =>) - it removes the differences in both implementation and behaviour.

The result is that the following two definitions mean the same thing:

def square(x: Int) = x*x
val square = (x: Int) => x*x

There is no reason for the latter form (immediate anonymous function assignment) to be used in any normal situation - it's simply possible to use it instead of the def form.

Would having such duplicate syntax for defining named functions hurt the orthogonality of the language or some other design aspect?

I prefer this solution because it allows for short and intuitive definitions of methods and named functions (via def), and short definitions of anonymous functions (using =>).

Edit: Scala does differentiate between the two - anonymous functions are not the same as methods defined with def in Scala. The differences are relatively subtle though - see the posts I linked before.

I verified that this is possible in Scala too. In SML it is not and you have to use fun to define a recursive function.
–
GiorgioJun 21 '14 at 15:39

3

The second form isn't really a special syntactical structure, the way def is. It's just a side effect of the fact that an anonymous function, say (x : Int) => x + 1 is an object, and objects can be assigned to values with val f = .... The language designers would have had to go out of their way to disallow the syntax. It's not quite the same as explicitly putting in the effort to support two different syntaxes that do (approximately) the same thing.
–
KChalouxJul 16 '14 at 19:09

3

The major benefit of doing something more than one way in a language is it is a great way to start unproductive religious debates which distract from the real problems (Thinking C++ here) .......
–
mattnzJul 16 '14 at 22:10

It is valid in Scala, it mostly works the same, but it does not mean the same thing - and if you'd make more complex examples (type polymorphism is not available for anonymous functions e.g.) - the differences would become more apparent.
–
jcoJun 21 '14 at 8:19

I think that having two constructs that mean the same thing but look different should be kept to an absolutely minimum in a language. Any duplication increases how difficult it is to read (and thus write/modify code in ) your language. Eliminating all duplication is unavoidable in a language that can create arbitrary constructs (for example, the equivalence of iteration vs recursion).

So in this case, I think it could be designed better here. A single way to define functions makes the most sense to me. In this case, it sounds like the two scala statements you have actually do have slightly different implications, which again is probably not good design (probably best to have something clear that states what the differences, like a keyword).

In fact, you can apply this principle not only to named functions, but to any function. Why have any difference in defining named functions and anonymous functions? In Lima, functions are always defined like this: fn[<arguments>: <statements>]. If you want it to be "named" you can assign it to a variable: var x = fn[<arguments: <statements>], and if you want to pass it in to another function anonymously: function[fn[<arguments: <statements>]]. If you want it hoisted, make it constant const var x = fn[<arguments: <statements>]. The single form makes it obvious that they mean the same thing.

I've found a fundamental difference between lambdas and def methods in Scala - that I am still not sure whether I want to implement. I have to do further research on it and then I'll report back on my decision.

Essentially, only methods can return - and when the keyword is used from a lambda, it actually returns from the encompassing method.

As I've said, I'm not sure whether I want this. But it could be justification enough for this syntax. Or maybe too dangerous because subtle differences can unexpectedly cause harm.