zackradisic / aussieplusplus

Programming language from down under
aussieplusplus.vercel.app
617 stars 14 forks source link

Anonymous Functions #15

Open bbrk24 opened 3 years ago

bbrk24 commented 3 years ago

I was messing around with callbacks, and I noticed something interesting:

G'DAY MATE!

IMPOHT ME FUNC HitTheSack;

THE HARD YAKKA FOR performAfter IS (callback, duration) <
    HitTheSack(duration);
    callback();
>

THE HARD YAKKA FOR helloWorld IS () <
    GIMME "Hello, World!";
>

I RECKON duration = 1000;

// What combinations of literal/variable are legal?
performAfter(helloWorld, 1000); // works
performAfter(helloWorld, duration); // works
performAfter(// wait, do function literals/closures even exist?
    1000);

CHEERS C***!

I don't have any ideas for what they would be called, but I'm not even sure words would be necessary -- they tend to be pretty punctuationful. Consider how the NOP lambda is []() { } in C++ and () => {} in JS.

Syntactically, I perfer how Swift and Ruby handle it, where the entire closure body is wrapped in braces (in contrast with the closure syntax in JS, which consists of multiple separate parts).

bbrk24 commented 3 years ago

Relatedly, this is legal:

G'DAY MATE!

THE HARD YAKKA FOR func1 IS () <
    GIMME "func1 called";
>

THE HARD YAKKA FOR func2 IS () <
    GIMME "func2 called";
>

func1 = func2;
func1(); // prints "func2 called"

CHEERS C***!

I'd think only variables declared with I RECKON should be mutable, and not ones declared with THE HARD YAKKA FOR ... IS.

jwfxpr commented 3 years ago

When I think of Australianisms for when you don't know, or don't want to use, a name, what stands out to me is "old mate"

How about

performAfter(OLD MATE () IS < GIMME "Oi mate"; GIMME "Clear off"; >, 1000);
bbrk24 commented 3 years ago

I'm not qualified to comment on the Australianism, but the syntax looks fine (and is reminiscent of older JS function() {}).

jwfxpr commented 3 years ago

I'd think only variables declared with I RECKON should be mutable, and not ones declared with THE HARD YAKKA FOR ... IS.

In addition to this, it would be nice to be able to declare an immutable variable. DEADSET?

I RECKON x = 1; // Mutable
I DEADSET RECKON y = 2; // Immutable
bbrk24 commented 3 years ago

@jwfxpr I asked someone who is more qualified to speak to the Australianisms than I am, and he basically said that: OLD MATE is fine; DEADSET feels odd there, and if constants are to use RECKON at all, then I FULLY RECKON feels more natural.

jwfxpr commented 3 years ago

Yep @bbrk24 , I FULLY RECKON works too! Looking at it again with fresh eyes, DEADSET seems better to me as a standalone statement, rather than part of I RECKON.

I FULLY RECKON a = 1;
DEADSET b = 2;

Both of those forms seem good to me 😊

zackradisic commented 3 years ago

I think I prefer I FULLY RECKON since it sounds more fluent. The lambda function syntax looks good to me!

I can get to work right away on implementing constants and making function declarations immutable.

bbrk24 commented 3 years ago

Before the anonymous functions are fully introduced, I want to point out an inconsistency with the proposed syntax: named functions have IS () < >; anonymous functions have () IS < >.

zackradisic commented 3 years ago

@bbrk24 Good point, the finalized syntax will be this then.

OLD MATE IS () < GIMME "Oi mate"; GIMME "Clear off"; >

Also this gave me idea that we should write style rules for the language, things like spacing, conventions, things of that nature

jwfxpr commented 3 years ago

Just so that the examples and discussion here are clear, we've implied (but not discussed) that parameters for old mates go inside the ().

I.e., old mate with no parameters:

OLD MATE IS () < GIMME "Oi mate"; GIMME "Clear off"; >

An old mate with one parameter:

OLD MATE IS (wotareya) < GIMME "Oi " + wotareya; GIMME "Clear off"; >

Old mate with two parameters:

OLD MATE IS (wotareya, yerawanka) < GIMME "Oi " + wotareya; GIMME YA RECKON yerawanka ? < "Bugger off"; > WHATABOUT ? < "Clear off"; > >

etc.

Sidebar q, @zackradisic: I could test this myself, but for the sake of discussion, are YA RECKONs expressions? README.md mentions "if statements", but if we're going to the trouble of implementing lambdas, it seems reasonable that a lambda would be able to use a single YA RECKON to BAIL a value, yes?

zackradisic commented 3 years ago

At this moment YA RECKON (if) and YA RECKON ... IS A (match) are statements, so this won't work:

I RECKON x = OLD MATE IS (yerawanka) <  
    BAIL YA RECKON yerawanka ? < "Bugger off"; > WHATABOUT ? < "Clear off"; >;
>(NAH YEAH!);

In retrospect I should have made them expressions, should make that change at some point.