Lambda expressions

Monkey Forums/Monkey Programming/Lambda expressions

ziggy(Posted 2014) [#1]
Not a feature request, but is anyone else missing them? Just being curious


Goodlookinguy(Posted 2014) [#2]
Yes, I want them badly, but I've also learned to live without.


Gerry Quinn(Posted 2014) [#3]
OO guy, never saw the point of them.


Goodlookinguy(Posted 2014) [#4]
I'm an OO guy too, doesn't mean that lambda expressions are pointless. There are very valid reasons to have them which can help cut down repeated code and functions that don't need to be named.

I'm going to assume you've never used them, because I didn't see a point in them until I used them. Same thing with interfaces. I saw no point until I started using them. It's a great tool to have in the toolbox that is a programming language.


ziggy(Posted 2014) [#5]
@Goodlookinguy: I agree with you. Also, being able to pass them as function or method parameters is almost sexy.


Gerry Quinn(Posted 2014) [#6]
I must admit, I only recently learned the point of interfaces...


Nobuyuki(Posted 2014) [#7]
I'm not missing them, unless you count Immediate-If as one. Some guy on these forums made a lambda expression support in trans and I think it would be cool to see it make its way into Monkey proper, but it might be a big change. Just something to bring up

I'd rather see lambda expressions than delegates, frankly; easier to wrap my head around I guess. I rely (probably too much) on interfaces in Monkey, kinda wish those supported generics. That's what I want. But official lambda expressions would be fantastic.


Goodlookinguy(Posted 2014) [#8]
Interfaces do support generics. They've supported generics for a few versions now.


Nobuyuki(Posted 2014) [#9]
@Goodlookinguy

Whaddayaknow, it is working again. I last had 76d and it wasn't working then, so I wasn't aware it's "in for reals" now. Mark had disabled the feature for a while because it was a bit buggy, so now that it's working I might go back and change some Comparator code of mine to better support this stuff. Provided it is officially-supported and not still buggy, of course :)


Goodlookinguy(Posted 2014) [#10]
I've been using interface generics since v76a (I jumped straight to 77e where it still worked) and haven't had any issues. I don't know what bugs there were as I never had any problems and I did use them a fair bit.

Back to the topic at hand, Lua has lambda expressions that would fit right in with Monkey syntax.


Paul - Taiphoz(Posted 2014) [#11]
I don't see the point in interface's and no I'v not bothered to use them, I can say the same about properties, whats the diff really a property just seems like extra code for no real benefit, I saw interfaces as the same, but I know there must be good reasons for them otherwise they would not exist, think I just need to see a practical example of why I might use one and why its better than an alternative .


Goodlookinguy(Posted 2014) [#12]
The Property keyword is for when you get or set something and can have other code run. It can also be used to make a field read-only. It removes the need for parenthesis because it's treated like a field.

Follow the links in my last post to see a practical (and robust) example of a hash map implementation using interfaces. Interfaces are used to communicate and encapsulate unrelated objects that have similar functionality. It removes the need for multiple inheritance which is the source of all evil.


Nobuyuki(Posted 2014) [#13]
@Goodlookinguy
Monkey has very little polymorphism in the keywords department. I think that's one of the reasons it's relatively simple/verbose, but it is what it is. Whereas similar syntaxes like VB have keywords which can mean a lotta different things depending on where they are contextually ("Is", "And", "Or", "Function", parenthesis defining array bounds, anonymous functions, etc, and last but not least the insane amounts of declaration prefixes), Monkey seems to only have "=" and separates out a lot of other things to their own keywords, such as separate logic/bitwise ops, scope directives being assigned separate from a declaring line, suffixes for method declaration modifiers, etc.

I feel like re-use of "Function" specifically for anonymous functions may or may not feel "just right" as of yet. I'm on the fence about it, because I don't know whether that represents monkey's feel more compared to say, the curly-brace solution Erik came up with. I had issues with the symbol-soup that ended up being, too, but, it's definitely more readable from a glance than VB's lambda syntax. A compromise between hard-to-read syntax + possibly unnecessary keyword polymorphism would be going with lua-like syntax, but making the keywords unique, like this:

'One possible way to do type inference.  Doesn't downcast to Int if Float
Lambda Pow(x,y) Returns x*y

'explicit type
Lambda Factorial:Int(n:Int) Returns If n>1 Then n+Factorial(n-1) Else 1


@Taiphoz

Properties are actually very useful; for one thing, you can use them as a tricky way to require fields in an Interface. But more importantly, you can use them to combine getter and setter functions into one member that you treat externally like a variable. This is great for classes that would require multiple states to be updated dependent on the underlying variable the property represents. Setting the underlying variable(s) that the property gets/sets to Private (or Protected, if Monkey ever gets it...) lets you only expose the Property, thus making it harder to accidentally screw up the state of your class by setting a value directly without giving the setter an opportunity to update the other member variables dependent on it.

As for interfaces, it's basically just a safe way to implement something akin to multiple inheritance. They're aptly named, because implementing an interface lets other classes access methods of other classes that may not inherit from each other at all. Like, for example, having a list of drawable objects that you want to do an order sort on -- you can have one master list contain layers, tiles, HUD elements, sprites, whatever, as long as they implement a drawable interface. You can use it to narrow a container from Object to only implementing interfaces, then be able to call the implementing method on a member safely without worrying about a crash or the target compiler exploding.


Goodlookinguy(Posted 2014) [#14]
Those curly braces just seem wrong. I don't think it'd be a stretch to have Monkey syntax use Lua-like syntax and have the keyword Function in minutely different context.

Example(Function:String()
	Return "Hello World"
End)


Example(Function:String(); Return "Hello World"; End)



Nobuyuki(Posted 2014) [#15]
That latter example's horrifying. And also something you can do right now, but it's not really a true anonymous function, because no delegation or passing functions as parameters etc etc It's late. I just realized you were specifying a function type.... I think

If you wanna give the toker something to bite into (IE: not a nightmare to add the feature), you probably wanna give it its own keywords. Func's what's used in .NET world, internally, iirc, though the actual keyword and syntax are reused from existing constructs, making it look a little confusing if you've never seen it before.


Erik(Posted 2014) [#16]
The curly braces was part of a larger macro system I had in mind. So { signals the start of a macro and ends with }. Prefix lisp like syntax like this is extremely powerful and trivial to parse. Inside the braces you could essentially write your own parser for whatever dsl you wanted. If you just reserve {} for user extensions to the langue you could have compatible syntax for many user additions to trans without clashes.

It could be implemented something like this:
Class Func1<T,R>
  Method Do:R(param:T) abstract
End

Class MacroDefinition Extends Func1<String,String>
'or perhaps
Class MacroDefinition Extends Func1<Enviroment,String>

Field Macros:StringMap<MacroDefinition>



You could imagine all sorts of macros like:

Macros.Set("(", New LambdaMacro) ' My lambda example
or if you prefer:
Macros.Set("Function", New LambdaMacro) ' My lambda example

Macros.Set("Shader", New ShaderMacro) ' Mini dsl for shaders
Macros.Set("Use", New UseMacro) ' Don't add to the garbage collector
Macros.Set("InlineC", New CMacro) ' Inline C code